![](/img/trans.png)
[英]How does java compiler know of generics type information of a code in jar?
[英]Eclipse autocompletion - how does it know about generics when only binary jar is available?
使用类型擦除实现Java泛型。 这意味着如果我有一个方法:
public void setMapParam(Map<String, Integer> p) { ... }
在编译之后,它将最终在.class中:
public void setMapParam(Map p) { ... }
我有一个JAR文件,其中包含如上所述的泛型类和方法。 它只是二进制文件。 没有源代码也没有。
但是当我在代码中使用它时,Eclipse自动完成给了我setMapParam(Map<String, Integer> p)
即使在二进制文件中就像setMapParam(Map p)
。
即使方法签名已被类型擦除(到Map
) Map<String, Integer>
Eclipse现在如何处理类型( Map<String, Integer>
)? 或者我错过了什么?
类型擦除并不意味着编译后的代码不包含任何类型的参数信息。 类和成员定义中使用的类型参数存在于已编译的代码中,并可通过反射获得(请参阅TypeVariable
)。
什么类型的擦除意味着对象实例没有单独的类型参数。 给定一个类定义MapImpl extends HashMap<T extends Comparable, Integer>
和该类的实例,您无法找出在创建该实例的代码中使用了什么特定的T
值,因为该信息不存在。 但是你可以发现它extends Comparable
并且值类型是Integer
,因为该信息是类定义的一部分(并由所有实例共享)。
不,参数保留其通用类型信息。
例如,类型擦除是关于List<T>
的实例,不知道T
在执行时是什么。 实际上只有一个List
类 - 其余的由编译器决定。 但编译器可以使用有关参数类型和类型本身的信息。
这是一个例子:
import java.util.*;
import java.lang.reflect.*;
public class Test {
public void foo(List<String> list) {
}
public static void main(String[] args) throws Exception{
Method method = Test.class.getMethod("foo", List.class);
Type parameterType = method.getGenericParameterTypes()[0];
System.out.println(parameterType);
}
}
打印出:
java.util.List<java.lang.String>
因此,类型信息已保留在方法的元数据中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.