据我了解,泛型是Java的编译时功能,编译后的字节代码中不存在参数化类型信息。我现在发现了Field#getGenericType和Method#getGenericReturnType方法,从而打破了我的世界观。请帮我把它拼凑起来。
答案 0 :(得分:7)
删除对象的正常运行时类型。例如:
Object obj = new ArrayList<String>();
obj.getClass()
将返回ArrayList.class
。您甚至可以告诉ArrayList
有一个通用参数。但无法判断obj
是否已创建为ArrayList<String>
,ArrayList<Integer>
,ArrayList<Object>
,ArrayList
(原始)或其他任何内容。
静态类型信息仍然存在于类,方法等中(尽管不适用于本地人)。这只是作为类文件中的属性附加的额外数据,并且在运行时可用。可以想象它与具有运行时保留的注释非常相似。有问题吗?
答案 1 :(得分:3)
当您在IDE中处理一罐编译的字节码时,您仍然可以获得通用的自动完成功能。这就是它的实现方式。基本上你是对的:类型没有完全删除。
答案 2 :(得分:3)
字段和方法的静态泛型类型信息必须存在于已编译的类文件中,以便在编译其他源代码时,编译器可以进行类型检查。例如,当您编写使用ArrayList<E>
类型变量的代码并在其上调用get()
方法时,您没有ArrayList
类的源代码。编译器查看已编译的类文件并获取get()
方法的泛型返回类型,并意识到它返回泛型类型E
,以便它可以进行类型检查。因此,必须存在泛型类型信息,以便编译器可以检查它。