Why we can't do
为什么我们做不到
List<Parent> mylist = ArrayList<child>();
3 个解决方案
#1
110
Suppose we could. Then this program would have to be fine:
假设我们可以。然后这个程序必须没问题:
ArrayList<Banana> bananas = new ArrayList<Banana>();
List<Fruit> fruit = bananas;
fruit.add(new Apple());
Banana banana = bananas.get(0);
That's clearly not type safe - you've ended up with an apple in the collection of bananas.
这显然不是类型安全的 - 你最终在香蕉系列中加入了一个苹果。
What you can do is:
你能做的是:
List<? extends Fruit> fruit = new ArrayList<Banana>();
this is safe, because the compiler won't then let you try to add to the list of fruit. It knows that it's a list of some kind of fruit, so you could write:
这是安全的,因为编译器不会让你尝试添加到水果列表中。它知道它是某种水果的清单,所以你可以写:
Fruit firstFruit = fruit.get(0);
but it doesn't know what exact kind of fruit it's a list of, and make sure you can't do the wrong thing.
但它不知道它是什么类型的水果,并确保你不能做错事。
See the Java generics FAQ another explanation.
请参阅Java泛型FAQ另一种解释。
#2
5
Because they're not the same type. Suppose you had another child class of Parent
(Child2
for the sake of argument), it would then be possible to put an instance of Child2
into a List<Parent>
, but type-incorrect to put it into an instance of List<Child>
. Covariant inheritance is a real headache, and is only supported at all in Java for array types (where it can cause odd problems).
因为它们不是同一类型。假设您有另一个子类Parent(为了参数而使用Child2),那么可以将Child2的实例放入List
#3
-3
It should be this way, because we can do: Parent A = new Child();
它应该是这样的,因为我们可以这样做:Parent A = new Child();
Edit : Wait, actually it works :
编辑:等等,实际上它有效:
List<Parent> list = new ArrayList<Parent>(); List<ChildA> tmp = new ArrayList<ChildA>(); list.addAll(tmp); List<ChildB> tmp2 = new ArrayList<ChildB>(); list.addAll(tmp2);
List
It's just that the direct cast is not supported.
这只是不支持直播。
#1
110
Suppose we could. Then this program would have to be fine:
假设我们可以。然后这个程序必须没问题:
ArrayList<Banana> bananas = new ArrayList<Banana>();
List<Fruit> fruit = bananas;
fruit.add(new Apple());
Banana banana = bananas.get(0);
That's clearly not type safe - you've ended up with an apple in the collection of bananas.
这显然不是类型安全的 - 你最终在香蕉系列中加入了一个苹果。
What you can do is:
你能做的是:
List<? extends Fruit> fruit = new ArrayList<Banana>();
this is safe, because the compiler won't then let you try to add to the list of fruit. It knows that it's a list of some kind of fruit, so you could write:
这是安全的,因为编译器不会让你尝试添加到水果列表中。它知道它是某种水果的清单,所以你可以写:
Fruit firstFruit = fruit.get(0);
but it doesn't know what exact kind of fruit it's a list of, and make sure you can't do the wrong thing.
但它不知道它是什么类型的水果,并确保你不能做错事。
See the Java generics FAQ another explanation.
请参阅Java泛型FAQ另一种解释。
#2
5
Because they're not the same type. Suppose you had another child class of Parent
(Child2
for the sake of argument), it would then be possible to put an instance of Child2
into a List<Parent>
, but type-incorrect to put it into an instance of List<Child>
. Covariant inheritance is a real headache, and is only supported at all in Java for array types (where it can cause odd problems).
因为它们不是同一类型。假设您有另一个子类Parent(为了参数而使用Child2),那么可以将Child2的实例放入List
#3
-3
It should be this way, because we can do: Parent A = new Child();
它应该是这样的,因为我们可以这样做:Parent A = new Child();
Edit : Wait, actually it works :
编辑:等等,实际上它有效:
List<Parent> list = new ArrayList<Parent>(); List<ChildA> tmp = new ArrayList<ChildA>(); list.addAll(tmp); List<ChildB> tmp2 = new ArrayList<ChildB>(); list.addAll(tmp2);
List
It's just that the direct cast is not supported.
这只是不支持直播。