Java Универсальная коллекция универсального типа с ограниченным символом - PullRequest
7 голосов
/ 20 мая 2010

Пожалуйста, помогите мне с этим:

Если 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

Что я здесь не вижу?

Ответы [ 3 ]

6 голосов
/ 20 мая 2010

При назначении переменной (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>>();
6 голосов
/ 20 мая 2010

Это неправильно, потому что если бы это было разрешено, то это было бы допустимо:

Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); 
cc.add(new Cage<Tiger>()); // legal -- Cage<Tiger> is a Cage<? extends Animal>

Cage<Tiger> находится в пределах объявления, но не определения, поэтому это могло бы привести к сбою.

2 голосов
/ 20 мая 2010

Вам нужно:

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));
...