public void example(Object o) {
if(o instanceof List<MyType>)
//do something
}
我明白,這是不可能的(和爲什麼它是不可能的)給定的Java泛型處理和類型擦除方式。
我的問題是,什麼是最好/最乾淨的方式來實現這一目標?或者我唯一能做的就是檢查o
是否爲List<?>
?
public void example(Object o) {
if(o instanceof List<MyType>)
//do something
}
我明白,這是不可能的(和爲什麼它是不可能的)給定的Java泛型處理和類型擦除方式。
我的問題是,什麼是最好/最乾淨的方式來實現這一目標?或者我唯一能做的就是檢查o
是否爲List<?>
?
也許通過檢查在運行時的對象類型,也許是這樣的:
if (o.getClass() == List.class) ...
很明顯,你必須深入挖掘對象的類類型,看它是否是一個精確匹配List<>
和列表的元素類型。
在運行時,列表
看起來'List'是一個接口,這可能是一個壞主意 – 2010-02-10 03:13:51
短檢查類型列表中所有的項目,它是無法確定Java中的泛型參數的類型,因爲這只是存在在編譯時和運行時之前被移除。
我的建議是,除非你絕對需要讓方法接受一個對象(例如符合接口規範或覆蓋Object.equals),以便將所需的正確類型作爲該方法的參數,並且用可能需要運行該方法的各種其他類型重載該方法。
您不能檢查超過o instanceof List<?>
。
您從Java泛型中獲得的類型安全性僅在編譯時發生。 像你這樣的方法(它接受一個對象,然後試圖弄清楚該怎麼做),在這個設計中效果並不好。 我明白爲什麼這樣一個動態的方法是必要的一段時間,但考慮版本補充它輸入參數:
public void example(Object o) {
if(o instanceof List<?>)
example((List)o); // can only hope that the type is correct here
}
public void example(List<MyType> list){
// do something
}
在那些可以使用的情況下,你獲得仿製藥的全部好處。在其他情況下,你必須依靠閱讀你的Javadoc的人,並只傳遞正確的類型。
什麼甚至以上方法不能做的是有List<TypeA>
和List<TypeB>
兩個不同的代碼路徑。如果這對你來說真的需要,可以考慮使用自己的包裝類型ListOfTypeA
,ListOfTypeB
。
取決於你需要做什麼,甚至有可能不會有必要看看刪除類型列表中作爲一個整體,只是在運行時類型的各個元件的工作:
for (Object o: list){
if (o instanceof TypeA){
}
if (o instanceof TypeB){
}
}
Java在編譯後會擦除泛型的類型信息,所以您不能以這種方式動態地檢查類型參數。
如果這個代碼的所有路徑限制類型參數,然後做:
// Return true if object is a list of MyType, false if it is not a list, or is
// empty
boolean isListOfMyType(Object o) {
if (o instanceof List) {
List<?> l = (List<?) o;
return (l.size() > 0 && (l.get(0) instanceof MyType)
}
return true;
}
是類型安全的,但如果該列表不爲空時纔會有效。如果不是,您需要修改上述內容以檢查所有項目是否通過了instanceof測試(或者如果您允許列表中有空值,則它們爲空)。
另一種替代方法是創建一個子類,該子類擴展爲ArrayList<MyType>
並使用 這表示您的instanceof
檢查。
最後但並非最不重要的一個實現List<MyType>
的子類將允許您使用Class.getGenericInterfaces()
方法獲取類型參數。有關詳細信息,請參見this。
對於上述兩種方法中的任何一種,您必須確保創建列表總是實例化這些類型之一。 IE瀏覽器。如果調用者去構建他們自己的ArrayList<MyType>
,它將無法工作。
與普遍接受的相反,很少知道類型擦除可以避免,這意味着被叫方確實有能力知道在通話過程中使用了哪些通用參數。
請看看: Using TypeTokens to retrieve generic parameters
感謝
這個問題聽起來很熟悉,好像人被要求在過去90天左右。嘗試查看[http://stackoverflow.com/questions/1004022/java-generic-class-determine-type]。 – 2010-02-10 03:19:50