在本教程中反思它指出:
[...]因为泛型是通过类型擦除实现的,它在编译期间删除了有关泛型类型的所有信息
我的知识是使用泛型,以便在编译时编译器可以检查类型安全性.即快速接近失败.但链接提到类型擦除会在编译期间删除通用信息.
das*_*ght 11
您引用的语句是正确的:编译器在编译过程中在内部使用泛型类型信息,在处理源时生成与类型相关的错误.然后,一旦验证完成,编译器就会生成类型擦除的字节代码,所有对泛型类型的引用都将替换为它们各自的类型擦除.
当您通过反射查看类型时,这一事实变得明显:所有接口,类和函数都变为非泛型,所有类型都绑定到泛型类型参数,并根据源中指定的泛型类型约束替换为非泛型类型码.虽然反射API确实具有在运行时访问与泛型*相关的一些信息的规定,但是当您通过反射访问类时,虚拟机无法检查完全兼容的通用类型.
例如,如果您创建类型的类成员List<String>并尝试设置List<Integer>它,编译器将抱怨.但是,如果你试图通过反射来做同样的事情,编译器就不会发现,并且代码将在运行时以与没有泛型的方式相同的方式失败:
class Test {
private List<String> myList;
public void setList(List<String> list) {
myList = list;
}
public void showLengths() {
for (String s : myList) {
System.out.println(s.length());
}
}
}
...
List<Integer> doesNotWork = new ArrayList<Integer>();
doesNotWork.add(1);
doesNotWork.add(2);
doesNotWork.add(3);
Test tst = new Test();
tst.setList(doesNotWork); // <<== Will not compile
Method setList = Test.class.getMethod("setList", List.class);
setList.invoke(tst, doesNotWork); // <<== This will work;
tst.showLengths(); // <<== However, this will produce a class cast exception
Run Code Online (Sandbox Code Playgroud)
*有关在运行时获取与泛型类型相关的信息的详细信息,请参阅此答案.
| 归档时间: |
|
| 查看次数: |
5080 次 |
| 最近记录: |