Рассмотрим следующий конструктор для класса Foo
(который для ясности не универсальный класс):
public Foo(T obj) { }
Это допустимый синтаксис для конструкторов, как и для обычных универсальных методов .
Но для чего нужен этот синтаксис? Обычно универсальные методы обеспечивают безопасность типа для своего возвращаемого типа и могут извлекать выгоду из вывода типа компилятором. Например:
Pair stringInt = Pair.of("asfd", 1234);
Но вызов конструктора всегда возвращает экземпляр его объявляющего класса, поэтому его параметры типа не влияют на возвращаемый тип. Вышеупомянутый конструктор можно было бы просто заменить его стиранием :
public Foo(Object obj) { }
Конечно, обобщения касаются не только безопасности типов для возвращаемых типов. Конструктор может просто захотеть ограничить тип передаваемого аргумента (ов). Однако приведенное выше рассуждение все еще применимо к параметру ограниченного типа:
public Foo(N number) { }
public Foo(Number number) { } //same thing
Даже параметры вложенного типа с границами обрабатываются с использованием подстановочных знаков:
public > Foo(L numList) { }
public Foo(List extends Number> numList) { } //same thing
Итак, что является допустимым вариантом использования универсального конструктора?