Java集合接口(例如,List
或Set
)定義了接受任何對象的contains
方法。檢查泛型類型
public boolean contains(Object o)
然而,當涉及到實施這種方法,我工作特別的收藏需要,我有一種類型是與類的泛型類型E
(即或者是E級,或兼容E的子類,或者如果E是接口,則實現E的類)。換句話說,如果o可鑄造成E型,那麼它是兼容的。這就提出一個問題,因爲Java擦除泛型類型的信息,所以這樣的事情是不可能的:
public boolean contains(Object o)
{
if(o instanceof E) // compile error due to type erasures
{
// ... check if this collection contains o
}
return false;
}
我的問題是什麼是完成這樣的事情的最好方法? Oracle Article on Type Erasures提到這是禁止的,但不提供任何解決此問題的方法。
我只能想到一個半優雅的方式來解決這個問題:
做強制轉換爲類型E.如果轉換失敗,鄰類型不能爲E或類型的子類E.
public boolean contains(Object o)
{
try
{
E key = (E) o; // I know it's unsafe, but if o is castable to E then the method should work
// check if this collection contains key
}
catch(ClassCastException e)
{
// invalid type, cannot contain o
}
return false;
}
雖然這會工作,但看起來很亂(我不喜歡以這種方式使用例外)。
有沒有更好的方法來實現這個相同的目標(改變方法簽名是不允許的)?
編輯:是的,這不起作用由於E被擦除對象:(
它工作嗎?你會得到一個未經檢查的鑄造編譯器警告。你永遠不會得到一個ClassCastException(除非'o'不是'E'的**擦除**的實例,可能是'Object')。 –
您能否詳細說明「要求我有一個與類的泛型E兼容的類型?」謝謝。 –
我同意 - 這是行不通的。你確實需要實際的類做適當的演員,可能會失敗。 –
StaxMan