2012-01-07 74 views
1

我遇到問題讓這種類型轉換正常工作。我的猜測是有界的通用通配符<? super SomeType >不適用於接口實現。類型與有界通配符不匹配?超類型

// sample class definitions 
public interface IFace<T> { ... } 
public class MyClass<T1, T2> { ... } 
public class UtilityClass<T> { 
    public List<MyClass<T, ? super IFace<T>>> getList() { ... } 
} 
public class Actor extends SomeObj implements IFace<TypeA> { ... } 

// use... 
UtilityClass<TypeA> utility = new UtilityClass<TypeA>(); 
List<MyClass<TypeA, Actor>> list = utility.getList(); 

Type mismatch: cannot convert from List<MyClass<TypeA, ? super IFace<TypeA>> to List<MyClass<TypeA, Actor>> 

回答

0

直覺上,人們可能會嘗試通過使通用的方法來解決這個問題:

public <X super IFace<T>> List<MyClass<T, X> getList() { ... } 

但是這句法是不允許的,因爲它通常使用super來輸入參數的下限是沒有意義的。請參閱這篇文章爲什麼一個很好的解釋:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

編輯:

看你的代碼,我想你可以在指定的類型參數的範圍是混亂superextends。它是有意義的,如果getList()返回List<MyClass<T, ? extends IFace<T>>>代替,因爲這被指定結合在的MyClass第二類型參數的(換言之該類型必須有一些實施IFace<T>)。

由於natix's answer points out,使用通配符泛型返回類型不鼓勵,因爲它有效地隱藏一部分返回的對象泛型類型的信息。取而代之的是,使該方法一般:

public <X extends IFace<T>> List<MyClass<T, X> getList() { ... } 

允許調用代碼指定的X貫通式inferrence類型。

+0

你是對的,謝謝。幾分鐘後,我會刪除我的答案。 – 2012-01-07 19:49:05

4

援引約書亞Bloch的Effective Java第二版:

不要使用通配符類型作爲返回類型。它會強制用戶在客戶端代碼中使用 通配符類型,而不是爲用戶提供額外的靈活性。

對於 類的用戶來說,正確使用通配符類型幾乎是不可見的。他們使方法接受他們應該接受的參數 並拒絕他們應該拒絕的參數。 如果一個班級的用戶必須考慮通配符類型 ,那麼012xx類的API可能有問題。

1

當您開始使用泛型時,真正的必讀內容是this tutorial。如果您閱讀第4頁上的'泛型和子類型'部分,您將會知道爲什麼會出現該錯誤。它無關的事實你正在使用的接口

+1

教程鏈接似乎被打破。以下是類似信息的鏈接:http://docs.oracle.com/javase/tutorial/java/generics/index.html – SteveT 2012-11-06 15:00:19