實例化類型變量,我想檢查是否實例化的類型泛型類的具有某些特性,例如:獲得的Java
class Foo<T> {
void bar() {
if (T instanceof Serializable) // does not compile
...
}
}
我想知道如果通用信息在運行時完全失去了什麼?這是否意味着無法完成我想要做的事情?
實例化類型變量,我想檢查是否實例化的類型泛型類的具有某些特性,例如:獲得的Java
class Foo<T> {
void bar() {
if (T instanceof Serializable) // does not compile
...
}
}
我想知道如果通用信息在運行時完全失去了什麼?這是否意味着無法完成我想要做的事情?
這是否意味着沒有辦法完成我想要做的?
你可以寫:
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)) {
...
}
}
}
編譯器應該在後臺執行此操作:-( – 2013-02-23 20:52:04
@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
尼斯閱讀,但我仍然看不到任何不兼容性,因爲允許'instanceof T' – 2013-02-23 21:03:10
你是對的,generic type information
在運行時丟失。它被稱爲Type Erasure。編譯器將刪除所有通用類型,並在運行時執行強制轉換(如有必要)。和所有的
「?我想知道如果通用信息在運行時完全失去」 - yup,確切地說 – 2013-02-23 20:42:31
即使類型參數*在運行時沒有被擦除,你的代碼仍然不會編譯,因爲'instanceof'的左邊參數必須是* reference *,而不是* type * 。例如,你不能寫'String instanceof Object'。 – ruakh 2013-02-23 20:44:14
'Serializable'不是你想要靜態地在接口類型上聲明的東西。它是實現類型的屬性,因此也是實例。 – 2013-02-23 21:00:48