鉴于以下课程
class Creature {}
class Animal extends Creature {}
class Dog extends Animal {}
以下列表
List<? super Animal> l1;
List<? extends Animal> l2;
这些命令中的哪一个会导致编译错误?
1) l1.add(new Dog())
2) l1.add(null)
3) Object a = l1.get(0)
4) l2.add(new Dog())
5) Creature c = l2.get(0))
我认为这是四,因为? extends Animal
不一定是Dog
的超类型,但我不完全确定。解释会有很多帮助:))
答案 0 :(得分:5)
行List<? super Animal> l1;
表示列表l1
可以实例化,以保存{em>超类型 Animal
的对象。示例:l1 = new LinkedList<Creature>();
行List<? extends Animal> l2;
表示列表l2
可以实例化,以保存Animal
的子类型的对象。示例:l2 = new LinkedList<Dog>();
假设列表已构建。
1)列表l1
可以被实例化以保存任何超类型的Animal
。由于Dog
是任何超类型Animal
的子类型,因此可以隐含地进行转换。编译。
2)总是编译。 List
的规范并不否认空值。运行时异常取决于列表实现是否允许null元素。 LinkedList允许空值。
3)隐式转换为超类型(每个对象都是类Object
的实例)总是编译。如果列表为空,则在运行时导致异常。
4)add
List<? extends Animal> l2
方法的签名为l2.Add(? extends Animal)
。当我们调用l2.Add(new Dog())
时,编译器无法确定类型?
是Dog
的超类型(因为它不知道?
是什么,因为我们使用List
接口而不是通过List
的实现来明确地调用该方法,因此它必须导致编译错误。
来自评论:“请注意,这个问题与引用容器时使用接口无关。发生相同的编译错误,例如ArrayList已经发生过在声明中使用而不是lList。“ - 德克
5)假设额外的括号是错误的。总是隐式转换为超类型编译。 Creature
是列表l2
可以容纳的任何内容的超类型。如果列表为空,则在运行时导致异常。
答案 1 :(得分:0)