为什么我不能将具有其他类型的实例分配给参数化变量?

时间:2013-01-03 15:07:17

标签: java generics

为什么我不能这样做:

LinkedList<Fruit> myFruits = new LinkedList<Apple>();

错误讯息:

Type mismatch: cannot convert from LinkedList<Apple> to LinkedList<Fruit>

以下区别在哪里?

Fruit fruit = new Apple();

4 个答案:

答案 0 :(得分:10)

考虑使用LinkedList<Fruit>可以做些什么 - 并考虑一下您希望此代码执行的操作:

LinkedList<Apple> apples = new LinkedList<Apple>();
LinkedList<Fruit> fruits = apples;
fruits.add(new Banana());

Apple apple = apples.getFirst(); // Safe at compile time, but it's a Banana!

转换是仅 的地方,因此在编译时失败是有意义的。现在你可以写的是:

LinkedList<? extends Fruit> myFruits = new LinkedList<Apple>();

...然后编译器不会让你添加任何东西到列表中,因为它不知道真正的元素类型是什么。同样,你可以写一下:

LinkedList<? super Apple> apples = new LinkedList<Fruit>();

现在你可以苹果添加到列表中,但是你无法获得列表中的 out ,因为你再也不知道它的类型是什么

答案 1 :(得分:1)

多态性根本不适用于generic types

LinkedList<Fruit>LinkedList<Apple>不同,即使 Fruit Apple的超类

请参阅此Answer

答案 2 :(得分:0)

因为那时您可以将Orange添加到myFruits,这不应该有效,因为实际列表是Apple的列表

例如(如果可以的话);

List<Apple> myApples = new LinkedList<Apple>();
List<Fruit> myFruits = new LinkedList<Apple>();
myFruits.add(new Orange());

现在myApples有一个Orange

答案 3 :(得分:0)

允许进行简单的分配,因为复制了引用并保持原始内容不受影响。

Apple apple = new Apple();
Fruit fruit = apple;
fruit = new Banana(); // apple is not touched and is still an Apple

而(AtomicReference是一个简单的集合)

AtomicReference<Apple> apple = new AtomicReference<>(new Apple());
AtomicReference<Fruit> fruit = (AtomicReference) apple; // warning but compiles.
fruit.set(new Banana()); // this alters apple as well, making it invalid!
Apple apple2 = apple.get(); // throws ClassCastException.