Пожалуйста, помогите мне с этим:
Если Lion IS-A Animal
и задано Cage<T>
:
Cage<? extends Animal> c = new Cage<Lion>(); // ok,
но
Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); // not ok
Чего я здесь не вижу?
Пожалуйста, помогите мне с этим:
Если Lion IS-A Animal
и задано Cage<T>
:
Cage<? extends Animal> c = new Cage<Lion>(); // ok,
но
Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); // not ok
Чего я здесь не вижу?
При присвоении переменной (Set<T>
) универсального типа T
без подстановочных знаков присваиваемый объект должен иметь точно T
в качестве своего универсального типа (включая все параметры универсального типа T
, подстановочные знаки и не подстановочные знаки). В вашем случае T
- это Cage<Lion>
, который не совпадает с типом Cage<? extends Animal>
.
Что вы можете сделать, поскольку Cage<Lion>
можно присвоить Cage<? extends Animal>
, это использовать тип подстановочного знака:
Set<? extends Cage<? extends Animal>> a = new Set<Cage<Lion>>();
Это неправильно, потому что если бы это было разрешено, то это было бы законно:
Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>();
cc.add(new Cage<Tiger>()); // legal -- Cage<Tiger> is a Cage<? extends Animal>
Cage<Tiger>
находится в пределах объявления, но не определения, поэтому это приведет к сбою.
Тебе нужно:
Set<? extends List<? extends Number>> cc = new HashSet<ArrayList<Integer>>();
Чтобы объяснить, почему... Я думаю, вернемся к более простой версии вашего примера:
Number a = new Integer(1); // OK
Set<Number> b = new HashSet<Integer>(); // not OK
это не работает, потому что это позволит
b.add(new Double(3.0));