У меня есть пара вопросов об общих подстановочных знаках в Java:
В чем разница между List<? extends T> и List<? super T>?
Что такое ограниченный подстановочный знак и что такое неограниченный подстановочный знак?
Переведено автоматически
Ответ 1
В вашем первом вопросе <? extends T> и <? super T> являются примерами ограниченных подстановочных знаков. Неограниченный подстановочный знак выглядит как <?> и в основном означает <? extends Object>. Это в общих чертах означает, что generic может быть любого типа. Ограниченный подстановочный знак (<? extends T> или <? super T>) накладывает ограничение на тип, говоря, что он либо должен расширять определенный тип (<? extends T> известен как верхняя граница), либо должен быть предком определенного типа (<? super T> известен как нижняя граница).
List<? extendsA> la; la = newArrayList<B>(); la = newArrayList<C>(); la = newArrayList<D>();
List<? super B> lb; lb = newArrayList<A>(); //fine lb = newArrayList<C>(); //will not compile
publicvoidsomeMethod(List<? extends B> lb) { Bb= lb.get(0); // is fine lb.add(newC()); //will not compile as we do not know the type of the list, only that it is bounded above by B }
publicvoidotherMethod(List<? super B> lb) { Bb= lb.get(0); // will not compile as we do not know whether the list is of type B, it may be a List<A> and only contain instances of A lb.add(newB()); // is fine, as we know that it will be a super type of A }
Ограниченный подстановочный знак подобен тому, что ? extends B где B - это некоторый тип. То есть тип неизвестен, но к нему можно добавить "привязку". В этом случае он ограничен некоторым классом, который является подклассом B.
Ответ 3
У Джоша Блоха также есть хорошее объяснение, когда использовать super и extends в этом видео-докладе о Google io, где он упоминает мнемонику производителя extends для super потребителя.
Из слайдов презентации:
Предположим, вы хотите добавить массовые методы в Stack<E>
void pushAll(Collection<? extends E> src);
– src является разработчиком E
void popAll(Collection<? super E> dst);
– dst является пользователем E
Ответ 4
Могут возникнуть ситуации, когда вам захочется ограничить типы, которые разрешено передавать в параметр типа. Например, метод, который работает с numbers, может захотеть принимать только экземпляры Number или его подклассов. Для этого и нужны параметры ограниченного типа.
Collection<? extendsMyObject>
означает, что он может принимать все объекты, которые имеют отношение IS- A к MyObject (т. Е. Любой объект, являющийся типом MyObject, или мы можем сказать, любой объект любого подкласса MyObject) или объект класса MyObject.
Например:
classMyObject {}
classYourObjectextendsMyObject{}
classOurObjectextendsMyObject{}
Затем,
Collection<? extendsMyObject> myObject;
будет принимать только MyObject или дочерние элементы MyObject (т.е. Любой объект типа OurObject, YourObject или MyObject, но не любой объект суперкласса MyObject).