List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrownjava文档说;
此外,当调用
方法时,会出现堆污染的情况。add方法的静态类型第二形式参数是String,但是该方法是用另一种类型的实际参数Integer调用的。但是,编译器仍然允许此方法调用。由于类型擦除,add方法(定义为List.add(int,E))的第二个形式参数的类型成为对象。因此,编译器允许此方法调用,因为在类型擦除之后,l.add方法可以添加任何类型为对象的对象,包括整数类型的
对象。
我的问题是关于我大胆的部分。我理解在第2行中,堆污染的发生是因为List引用了一个类型为List的对象。但是,当对l引用调用add方法时,不应该期望数字类型而不是字符串类型,因为l是对ArrayList的引用。或者,在ls=l之后,堆中的空间也是由List<String>构成的,用于l引用吗?在本例中,java文档在粗体部分中的内容是有意义的。
发布于 2011-08-19 08:25:36
,但是当对l引用调用add方法时,它不应该期望数字类型而不是字符串类型,因为l是对ArrayList的引用。
List l被声明为非类型化列表。因此,编译器将允许您输入您喜欢的任何内容(并对其发出警告),并将其分配给不兼容的List<String>变量(并对其发出警告)。
如果您说的是List<Number> l,编译器将强制执行正确的类型(而不允许将它分配给ls)。
无论您声明或不声明哪种泛型类型,这在运行时都没有任何影响。为了保持向后兼容性,泛型是一个完整的编译时特性.
还是说,ls=l之后堆中的空间也是由List构成的呢?
如果你说
List l = new ArrayList<Integer>();
List<String> ls = l;
Object x = ls;
Collection<?> c = (Collection) x;您有四个不同的变量(有四个不同的类型声明),但它们都指向相同的数据(堆上的相同对象)。
发布于 2011-08-19 08:26:02
错误在第一行。您将l声明为非类型安全列表。将第一行改为:
List<Number> l = new ArrayList<Number>();https://stackoverflow.com/questions/7118784
复制相似问题