2017-05-27 23 views
0

說..,Java編譯器將刪除所有類型的信息,並取代那些與他們的上限(如果提到)或對象的所有出現..Java泛型 - 糾刪機制

我的問題是:沒有管型插入發生在這裏。當一些其他類被編譯爲這種類型的無信息類時,後來發生Casting,其中,取決於其他類補充的類型參數,泛型類被重新編譯(第二次),並且所有的類都被放置到位並且班級已準備好運行時間了,對嗎?

回答

4

不,該類不重新編譯。這些演員發生在具體類型和泛型類型之間的邊界上。

如果你想弄明白,你可以看看使用泛型類作爲原始類型(即沒有泛型)。例如ArrayList

List l = new ArrayList(); // An `ArrayList<String>` before generics. 

l.add("Hello"); 
String s = (String) l.get(0); 

的鑄件被插入其中的具體類型是已知的(在這種情況下String)。他們是而不是插入ArrayList類中,並不是真的需要這個。當一些其他類對這種 型無信息類編譯

+0

謝謝。所以演員們真的在用戶類中,而不是泛型類,對嗎?另外,參考上面的示例,如果我們指定列表,那麼顯式插入的字符串將被Java編譯器自動插入,對吧? – Searcherer

+2

@Searcherer是的,演員在用戶的班級。刪除ArrayList的類型參數是Object,但只有在用戶類中需要更具體的類型,這就是你投射的地方。是的,在'ArrayList '的情況下,該演員將自動插入。請注意,「add」方法沒有強制轉換。 –

+0

非常感謝。我只想問一個最後的小問題:關於你關於add方法沒有強制轉換的說明,編譯器仍然提供了針對add的簽名提供的參數,這可能會根據類型參數而有所不同,因此拒絕無效參數。對? – Searcherer

0

鑄造發生後,

沒有,在類本身的編譯階段進行鑄造。
編譯後的類不應根據依賴的類進行更改。

看看這個方法:

public class TestCast { 

    public void doSomething(){ 
     List<Integer> values = new ArrayList<>(); 
     values.add(1); 
     Integer value = values.get(0); 
    } 
} 

這裏是TestCast編譯的類的拆卸方法(與javap工具來完成):

public void doSomething(); 
    Code: 
     0: new   #15     // class java/util/ArrayList 
     3: dup 
     4: invokespecial #17     // Method java/util/ArrayList."<init>":()V 
     7: astore_1 
     8: aload_1 
     9: iconst_1 
    10: invokestatic #18     // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
    13: invokeinterface #24, 2   // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 
    18: pop 
    19: aload_1 
    20: iconst_0 
    21: invokeinterface #30, 2   // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object; 
    26: checkcast  #19     // class java/lang/Integer 
    29: astore_2 
    30: return 

演員確實是由編譯器添加的:

26: checkcast  #19     // class java/lang/Integer 
0

沒有其他的東西目前提到的答案是橋樑方法。

例如

public class GenericTest implements Comparable<GenericTest>{ 

    @Override 
    public int compareTo(GenericTest o) { 
     return 0; 
    } 
} 

編譯器實際上會創建兩個方法。 int compareTo(Object);轉換和預期int compareTo(GenericTest)