2013-02-23 67 views
0

實例化類型變量,我想檢查是否實例化的類型泛型類的具有某些特性,例如:獲得的Java

class Foo<T> { 
    void bar() { 
    if (T instanceof Serializable) // does not compile 
     ... 
    } 
} 

我想知道如果通用信息在運行時完全失去了什麼?這是否意味着無法完成我想要做的事情?

+3

「?我想知道如果通用信息在運行時完全失去」 - yup,確切地說 – 2013-02-23 20:42:31

+4

即使類型參數*在運行時沒有被擦除,你的代碼仍然不會編譯,因爲'instanceof'的左邊參數必須是* reference *,而不是* type * 。例如,你不能寫'String instanceof Object'。 – ruakh 2013-02-23 20:44:14

+0

'Serializable'不是你想要靜態地在接口類型上聲明的東西。它是實現類型的屬性,因此也是實例。 – 2013-02-23 21:00:48

回答

6

這是否意味着沒有辦法完成我想要做的?

你可以寫:

class Foo<T> { 
    private final Class<T> clazz; 

    Foo (final Class<T> clazz) { // require creator to supply a Class<T> 
    this.clazz = clazz; 
    if (clazz == null) { 
     throw new NullPointerException(); 
    } 
    } 

    void bar() { 
    if (Serializable.class.isAssignableFrom(clazz)) { 
     ... 
    } 
    } 
} 
+0

編譯器應該在後臺執行此操作:-( – 2013-02-23 20:52:04

+2

@JanDvorak:的確,根據* Java語言規範*,「涉及Java編程語言類型系統的最具爭議的設計決策之一」[第4.7節「可定義類型」](http://docs.oracle.com/javase/specs/jls /se7/html/jls-4.html#jls-4.7)解釋了爲什麼他們這樣做了,簡而言之,這是因爲他們希望新代碼可以繼續使用預編譯的舊代碼。 – ruakh 2013-02-23 20:59:31

+0

尼斯閱讀,但我仍然看不到任何不兼容性,因爲允許'instanceof T' – 2013-02-23 21:03:10

2

你是對的,generic type information在運行時丟失。它被稱爲Type Erasure。編譯器將刪除所有通用類型,並在運行時執行強制轉換(如有必要)。和所有的