
您引用的语句是正确的:编译器在编译过程中在内部使用通用类型信息,在处理源时会生成与类型相关的错误。然后,一旦完成验证,编译器将生成类型擦除的字节码,所有对泛型类型的引用都将替换为它们各自的类型擦除。
当您通过反射观察类型时,这一事实变得显而易见:所有接口,类和函数都变为非泛型,所有与泛型类型参数绑定的类型都将根据源中指定的泛型类型约束替换为非泛型类型码。尽管反射API确实提供了在运行时访问与泛型*相关的某些信息的规定,但是当您通过反射访问类时,虚拟机无法检查确切的泛型类型的兼容性。
例如,如果您将类型的类成员
List<String>设为type 并尝试将其设置为type
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 compileMethod setList = Test.class.getMethod("setList", List.class);setList.invoke(tst, doesNotWork); // <<== This will work;tst.showLengths(); // <<== However, this will produce a class cast exceptionideone上的演示。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)