2011-08-29 53 views
3

我有兩個變量如何找到Collection類型?

Collection<Service> services = new ArrayList<Service>(); 
Collection<Subscription> subscriptions = new ArrayList<Subscription>(); 

,我有以下的方法,我不知道我怎樣才能找到的價值「?」在這種方法中,或者如何找到服務是否已通過或訂閱是否已通過?

myMethod(Collection<?> myCollection) { 

    if (myCollection is of type Service) { 
     // process service 
    } 
    else if (myCollection is of type Subscription) { 
     // process subscription 
    } 
} 

謝謝。

+1

如果您需要該類型的知識,則不應使用通配符。只需爲每種類型的集合分別設置不同的方法。 – dlev

+0

我必須使用相同的方法名稱aka重載,但在編譯時myMethod(Collection )和myMethod(Collection )將被視爲重複方法,因此我試圖在一個方法中使用if/else。 – Rizwan

+0

你是對的;我忘記了刪除類型。 – dlev

回答

4

你不能。 Java具有基於擦除的泛型,這意味着類型參數在運行時不可用。

如果您的收藏夾不是空的,當然可以在第一個元素上做一個instanceof或其他東西。

+0

感謝您的回覆,我還認爲在第一個元素上執行instanceof會有所幫助,但我想知道是否有另一種方式,但看起來沒有。 – Rizwan

2

在通用方法中使用if-else構造會影響泛型的目的。如果您需要知道在運行時傳入的內容的類型,它實際上不應該是通用的,您應該爲每種類型編寫一個單獨的方法。

+0

我同意,這是一個糟糕的設計,但我不是設計師,設計給了我,我無法改變它。該設計是由我們的「設計團隊」完成的...... – Rizwan

2

你不能(除了by using reflection),因爲泛型類型參數在編譯期間被擦除。

我建議你重新考慮一下你的設計,而不是試圖用泛型來解決它。將任意類型的集合傳遞給相同的方法是長期存在的問題的祕訣。

+1

即使反射也無法獲取類型參數;像你說的那樣,它已經被刪除了! –

+0

@Chris,我找不到原來的帖子,我看到這個,但發現另一個,請參閱我的答案中的鏈接。 –

+0

重新編輯:這是得到_parameter_的類型,而不是傳入的對象。唉,實際活物體的類型參數實際上已被刪除。 –

1

沒有Java方法來做到這一點。類型擦除妨礙。如果你需要這樣做,這也可能是一個設計問題。 但是,如果你一定要,還有可怕的方式做幾乎是:

更改變量

Collection<Service> services = new ArrayList<Service>(){}; 
Collection<Subscription> subscriptions = new ArrayList<Subscription>(){}; 

注意{}後的()。您不是創建ArrayList,而是從ArrayList繼承的匿名類。類型擦除不適用於那裏。所以你可以通過做類似

private static Class<?> detectType(Collection<?> col) { 
    return (Class<?>) ((ParameterizedType) col.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
} 

這個方法將返回實際的類。它確實有效,它令人噁心。它是由你決定。