generics中的通配符:“? 超级T“工作时”? 延伸T“不?
我的问题是关于Java 7中的generics。假设我们有这样的类层次结构:
interface Animal {} class Lion implements Animal {} class Butterfly implements Animal {}
就像在Java Generics Tutorial中一样
我们还有一堂课
class Cage { private List arr = new ArrayList(); public void add(T t) { arr.add(t); } public T get() { return arr.get(0); } }
以下是使用该类的代码:
public static void main(String[] args) { Cage cage = new Cage(); Animal a = cage.get(); //OK cage.add(new Lion()); //Compile-time error cage.add(new Butterfly()); //Compile-time error }
问题#1:
我在这里读过这些问题,但就像Cage
。 但我告诉编译器
所以
Cage
T
类型将是Animal类型的任何子类型。 那为什么它仍然会产生编译时错误?
问题2:
如果我指定Cage cage = ...
Cage cage = ...
而不是Cage cage = ...
Cage cage = ...
一切正常,编译器没有说什么不好。 为什么在这种情况下它工作正常,而在上面的例子中失败?
笼子必须能够容纳两种类型的动物。 “超级”说 – 它说凯奇必须能够容纳所有类型的动物 – 也许还有其他一些东西,因为? super Animal
? super Animal
可能是? super Animal
的超类。 “延伸”说它可以容纳某些种类的动物 – 例如,可能只是狮子会,如:
Cage extends Animal> cage = new Cage();
这将是一个有效的陈述,但显然狮子笼不会持蝴蝶,所以
cage.add(new Butterfly());
不会编译。 该声明
cage.add(new Lion());
也不会编译,因为这里的Java正在查看笼子的声明 – Cage extends Animal>
Cage extends Animal>
– 不是现在分配给它的对象( Cage
)。
我所知道的generics的最佳描述是在O’Reilly的Java中的Nutshell中 。 本章免费在线 – 第1 部分和第2部分 。