Comma или амперсанд с многократно ограниченными типами?
В Java, являются ли запятые и амперсанды действительными при объявлении многократно ограниченного типа?
class MyClass <T extends OtherInterface, SomeInterface>
class MyOtherClass <T extends OtherInterface & SomeInterface>
Ответы
Ответ 1
Как указывали другие, это:
class MyOtherClass <T extends OtherInterface & SomeInterface>
определяет параметр с ограниченным ограничением. Если вы используете MyOtherClass
, вы должны указать ему тип, который реализует как OtherInterface
, так и SomeInterface
.
Однако это не определяет параметр с ограниченным числом типов:
class MyClass <T extends OtherInterface, SomeInterface>
Он определяет общий параметр с двумя параметрами типа. Первый должен реализовать OtherInterface
. Второй может быть любым. Это точно так же, как
class MyClass <T extends OtherInterface, U>
за исключением того, что вы назвали его SomeInterface
вместо U
. (Соглашение состоит в том, что параметры типа обычно представляют собой одиночные буквы верхнего регистра, или иногда буквы верхнего регистра, а также цифру или короткий идентификатор верхнего регистра. Но компилятору все равно. Он не будет смотреть на форму идентификатор, чтобы понять, что вы действительно подразумевали его как интерфейс.)
Ответ 2
нашел следующие правила:
Несколько границ
В предыдущем примере показано использование параметра типа с одной границей, но параметр типа может иметь несколько границ:
Переменная типа с несколькими ограничениями является подтипом всех типов, перечисленных в ссылке. Если одна из границ является классом, она должна быть указана первыми. Например:
Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }
class D <T extends A & B & C> { /* ... */ }
Если привязка A сначала не указана, вы получаете ошибку времени компиляции:
class D <T extends B & A & C> { /* ... */ } // compile-time error
Ответ 3
Возможны множественные границы с <T extends B1 & B2 & B3>
, где B2 и B3 должны быть интерфейсом. B1 может быть простым классом или интерфейсом
Ответ 4
Запятые и амперсанды в определении типа связаны между собой разными вещами.
Амперсанд означает, что ваш параметр типа является подтипом всех границ параметров типа, соединенных '&'; как и следовало ожидать, список ограничений параметров типа должен соответствовать правилам множественного наследования Java, т.е. в большинстве классов допускается несколько интерфейсов.
Запятая - это разделитель для захваченных границ типа, поэтому в вашем примере это означает, что у вас есть два отдельных аргумента типа: T extends OtherInterface и SomeInterface, поэтому вам нужно будет использовать его как:
new MyClass<OtherInterfaceSubtype, SomeInterfaceSubType>();
Я предполагаю, что это не то, что вы хотите.