【发布时间】:2013-01-03 15:07:17
【问题描述】:
为什么我不能这样做:
LinkedList<Fruit> myFruits = new LinkedList<Apple>();
错误信息:
Type mismatch: cannot convert from LinkedList<Apple> to LinkedList<Fruit>
与下面的区别在哪里?
Fruit fruit = new Apple();
【问题讨论】:
为什么我不能这样做:
LinkedList<Fruit> myFruits = new LinkedList<Apple>();
错误信息:
Type mismatch: cannot convert from LinkedList<Apple> to LinkedList<Fruit>
与下面的区别在哪里?
Fruit fruit = new Apple();
【问题讨论】:
考虑您可以使用 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>();
... 然后编译器不会让你 add 任何东西到列表中,因为它不知道真正的元素类型是什么。同样你可以写:
LinkedList<? super Apple> apples = new LinkedList<Fruit>();
现在您可以将苹果添加到列表中,但是您无法将苹果从列表中移出,因为您也不知道苹果的类型是什么.
【讨论】:
多态性根本不适用于generic types。
LinkedList<Fruit> 与 LinkedList<Apple> 不同,尽管 Fruit 是 Apple 的超类。
原因参考这个Answer。
【讨论】:
因为那时您可以将 Orange 添加到 myFruits 并且这不应该工作,因为实际列表是 Apple 的列表
例如(如果你能做到的话);
List<Apple> myApples = new LinkedList<Apple>();
List<Fruit> myFruits = new LinkedList<Apple>();
myFruits.add(new Orange());
现在 myApples 里面有一个 Orange
【讨论】:
允许进行简单的赋值,因为引用被复制而原件保持不变。
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.
【讨论】: