В чем разница между "супер" и "расширением" в Java Generics
Я пытаюсь изучить Java-дженерики. Я не понимаю, когда вы будете использовать <T extends Foo>
и когда вы будете использовать <T super Foo>
. Что означает каждая из этих вещей о Т? Допустим, у меня есть <T extends Comparable>
и <T super Comparable>
, что означают каждый из них?
Я читал несколько руководств на sun.com, но я все еще потерян. Может ли кто-нибудь проиллюстрировать примеры?
Спасибо!
Ответы
Ответ 1
См. "Эффективное Java 2-е издание", пункт 28:
PECS
P roducer e xtends, C onsumer s uper
Если ваш параметр является производителем, он должен быть <? extends T>
, если это потребитель, он должен быть <? super T>
.
Взгляните на Коллекции Google, они знают, как использовать его, потому что они получили Блох;)
Ответ 2
Это зависит от того, какой путь можно использовать в иерархии наследования. Предположим, у вас есть класс "Ребенок", который наследует от "Родитель", который наследуется от "Бабушки и дедушки".
<T extends Parent>
принимает родительский или дочерний элемент, а <T super Parent>
принимает родительский или дедушка.
Ответ 3
Существует три типа подстановочных знаков:
-
? extends Type
: Обозначает семейство подтипов типа Type
. Это самый полезный шаблон.
-
? super Type
: Обозначает семейство супертипов типа Type
.
-
?
: Обозначает набор всех типов или любых.
Ответ 4
Для меня лучший ответ пришел из @BSingh, когда я прочитал статью дяди Боба. Я возобновляю здесь, заключение статьи.
Использовать список < T супер Костюм > всякий раз, когда вы переходите к пишите в список.
Когда вы помещаете объект в список, все, о чем вы заботитесь, это то, что объект имеет тип, совместимый с типом, хранящимся в списке. Таким образом, вы хотите, чтобы список взял тип этого объекта или любой из суперклассов этого объекта.
Использовать список < T расширяет Костюм > всякий раз, когда вы переходите к читать из списка.
С другой стороны, когда вы читаете из списка, вы хотите, чтобы тип, который вы читаете, был типом, содержащимся в списке, или производным от этого типа.
Ответ 5
Если вы спрашиваете о параметрах типа, то в Java нет конструкции <T super X>
. Ограниченный параметр может быть только extend
, но он может распространяться более чем на один тип. Например
public class MyClass< T extends Closeable & Runnable >
{
// Closeable and Runnable are chosen for demonstration purposes only
}
В этом случае, если вы видите MyClass< ConcreteT >
, то ConcreteT должен быть объявлен как
public class ConcreteT
implements Closeable, Runnable
{
...
}
Для ограниченных подстановок читайте в этой статье. Читайте раздел о принципе get-put. В принципе, super
соответствует семантике write
, а extends
соответствует семантике read
.
Ответ 6
Помните, что PECS - продюсер продлевает потребительскую поддержку. Кроме того, дядя Боб обсуждает это в своей серии мастеров. Проверьте http://objectmentor.com/resources/articles/The_Craftsman_44__Brown_Bag_I.pdf