в чем разница между ? и T в сигнатурах класса и метода? - PullRequest
13 голосов
/ 27 сентября 2011

почему

public interface ArrayOfONEITEMInterface <T extends ONEITEMInterface>{
    public List<T> getONEITEM();
}

компилируется, а не

public interface ArrayOfONEITEMInterface <? extends ONEITEMInterface>{
    public List<?> getONEITEM();
}

в чем разница?и T в сигнатурах класса и метода?

Ответы [ 4 ]

23 голосов
/ 27 сентября 2011

? является подстановочным знаком и означает любой подкласс ONEITEMInterface, включая самого себя.

T является специфической реализацией ONEITEMInterface в этом случае.

Так как ? является подстановочным знаком, между вашим ? в объявлении класса нет никакой связи и ? в объявлении вашего метода, поэтому он не будет компилироваться. Просто List<?> getONEITEM(); будет компилироваться.


Первый сценарий означает, что весь класс может обрабатывать ровно один тип Bar на экземпляр .

interface Foo<T extends Bar> {
     List<T> get();
}

Второй сценарий позволяет каждому экземпляру работать с любым подтипом Bar

interface Foo {
     List<? extends Bar> get()
}
3 голосов
/ 27 сентября 2011

Предложение <T extends ONEITEMInterface> объявляет параметр типа с именем T.Это позволяет вашему универсальному типу ArrayOfONEITEMInterface ссылаться на параметр в другом месте.Например, вы можете объявить метод типа void add(T t).

Не называя параметр типа, как бы вы к нему обратились?Если вы никогда не обращаетесь к параметру типа, почему ваш тип вообще универсален?Например, вам не нужен параметризованный тип, чтобы делать что-то вроде этого:

public interface ArrayOfONEITEMInterface {
    List<? extends ONEITEMInterface> getONEITEM();
}

Не имеет смысла объявлять параметр анонимного типа, поэтому он синтаксически недопустим.

2 голосов
/ 27 сентября 2011

T - это заполнитель для типа, который будет предоставлен классом реализации или создания экземпляра.

? это заполнитель, который говорит: «Я не знаю или неважно, что такое универсальный тип», обычно используемый, когда работа, которую вы будете выполнять над объектом-контейнером, не должна знать тип.

Причина, по которой вы не можете использовать '?' в определении класса / интерфейса это потому, что есть значение, определяющее имя заполнителя (и тип будет предоставлен в другом месте). Ставить '?' не имеет смысла.

Кроме того, заполнитель не обязательно должен быть T, он может использовать любую стандартную переменную Java. По соглашению, это один заглавный символ, но не обязательно.

1 голос
/ 27 сентября 2011

?позволяет вам иметь список Неизвестных типов, где T требует определенного типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...