Почему мы можем создать экземпляр Pair<T>, но не можем с Pair<?>
Так почему же мы можем создать экземпляр Pair, но не можем создать экземпляр Pair
Pair<T> p=new Pair<T>();
В.С.
Pair<?> p=new Pair<?>();
я знаю это <?>
значит неизвестный тип -> <? extends Object>
но не <T>
означать то же самое ---> <T extends Object>
У кого-нибудь есть идея?
3 ответа
Нет? и Т не одно и то же.? представляет параметр универсального типа подстановочного знака - это может быть что угодно во время выполнения. T
представляет параметр общего типа, который будет определенным типом во время выполнения - мы просто не знаем его во время компиляции.
Это List<?>
может содержать строки, целые числа, числа с плавающей точкой и т. д. A List<T>
может содержать только то, что T
параметризован как.
<T>
сам по себе ничего не значит. T
Тип должен быть определен где-то на уровне класса или метода, например:
public class PairFactory<T> {
public Pair<T> makePair() {
return new Pair<T>();
}
}
В этом случае вы решаете на <T>
во время создания экземпляра:
new PairFactory<String>();
Это немного сложнее:
public <T> Pair<T> makePair() {
return new Pair<T>();
}
Компилятор попытается выяснить тип на основе контекста, например:
Pair<Date> p = makePair();
Вы не можете создавать экземпляры с подстановочным знаком в качестве параметра, потому что это, как правило, бесполезно. Вместо этого вы можете просто использовать любой ссылочный тип, который находится в пределах параметра type (в этом случае границ нет, поэтому просто любой ссылочный тип):
class SuperCrazyBogusType { }
Pair<?> p = new Pair<SuperCrazyBogusType>();
(или вы можете использовать более обычный тип, как Object
).
Вы видите, как это странно? Да, вы можете создавать экземпляры любого произвольного типа, даже те, которые не имеют никакого отношения к остальной части вашей программы или к тому, что вы делаете. И да, это на 100% безопасно и правильно, потому что все, что вы хотели, это Pair<?>
(пара какого-то неизвестного типа).
Это указывает на то, почему это смешно, и почему синтаксис для этого не нужен. Вы почти ничего не можете сделать с Pair<?>
вы получаете (например, вы не можете поместить в него какие-либо данные), потому что вы не знаете параметр типа.