![](/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.