Почему мы можем создать экземпляр 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<?> вы получаете (например, вы не можете поместить в него какие-либо данные), потому что вы не знаете параметр типа.

Другие вопросы по тегам