Объяснение
Вводя общий параметр T
, вы даете пользователю своего класса возможность установить тип для вас.
Обобщения действуют так же, как параметры для методов, но параметры типа для классов .
extends Tuple
является ограничением для пользователя. Таким образом, ваш пользователь может использовать IntTuple
, например. Ваш метод говорит, что возвращает T
, но на самом деле возвращает только Tuple
. Когда пользователь устанавливает общий параметр на IntTuple
, метод также должен будет возвращать IntTuple
, а не Tuple
.
Пример
Рассмотрим следующий, немного более читаемый пример:
public class Farm<A extends Animal> {
public A produce() {
// ...
}
}
Пользователь может использовать ферму следующим образом:
Farm<Pig> pigFarm = new Farm<>();
Pig pig = produce();
Важной частью здесь является то, что produce
сейчас должны выдавать Pig
с. И если у другого пользователя есть Farm<Cow>
, эта ферма должна выдать Cow
с.
Однако ваша текущая реализация была:
public A produce() {
return new Animal();
}
Но Animal
- это , а не Pig
или Cow
. Так что не может работать. Он будет (теоретически) работать только в том случае, если пользователь (по какой-либо причине) будет использовать Farm<Animal>
.
Решение
Весьма вероятно, что вы намеревались сделать что-то совершенно другое. Итак, теперь, когда вы поняли проблему, переосмыслите свой дизайн.
Может быть, вы вообще не хотели генериков и просто возвращаете Animal
, отбрасывая T
.
Возможно, вы действительно хотите вернуть T
, но захватите фактический T
экземпляр из другого места. Создание нового экземпляра T
с помощью этого метода будет довольно трудным, поскольку вы не знаете точный тип T
, который будет установлен пользователем. Cow
может иметь конструкторы, отличные от Pig
.
Примечание
Другие ответы предлагают привести к T
, но это, скорее всего, не даст того, что вы намеревались сделать. Это способ сделать этот код каким-то образом компилируемым. Затем он будет поддерживать Tuple
, но без подклассов. В примере это отражает Farm<Animal>
. И он потерпит неудачу с ClassCastException
для всех других входов. Поскольку Animal
нельзя преобразовать в Pig
и т. Д.