2017-02-10 75 views
4

在我不期望的情況下,出現類型不匹配的錯誤。在Java中編寫泛型類型

public interface I {} 

public abstract class C {} 

public class A extends C implements I {} 

public class B extends C implements I {} 

public class Foo { 

    public <T extends C & I> T getComposition(String selector) { 
     switch (selector) { 
      case "a": return new A(); // type-mismatch! 
      case "b": return new B(); // type-mismatch! 
     } 
    } 

} 

爲什麼A,這既是CI,不能返回的T

+5

如果我把你的方法稱爲'foo。 getComposition()',這個方法應該返回一個'Hello'的實例,但它返回一個'A'的實例。 A擴展C&I.T也是。但這並不意味着T和A是同一班。 –

+0

我錯過了!謝謝@JBNizet。 –

+0

@JBNizet這個解釋是有道理的,但是你能指出一些關於泛型方面的更多的閱讀嗎?至少從我的角度來看,如果這將是一個答案,我會upvote,;-) – GhostCat

回答

4

符號<T extends C & I>表示T類型參數。這意味着當有人調用函數時,他們必須指定這種類型。唯一的限制是該類型延伸CIA就是這樣一種類型,但我可以創建一個新類,它也擴展了CI。像這樣的例子:

class B extends C implements I {} 

Foo foo = new Foo(); 
B b = foo.<B>getComposition(); 

如果你的榜樣編過,這將導致異常,因爲A是不一樣的類型B

如果您確實想要返回A,則需要刪除通用參數並直接返回A。像這樣:

public class Foo { 
    public A getComposition() { 
     return new A(); 
    } 
} 
+0

有沒有一種方法來表達這樣的「東西」,使用泛型,但與那個'新的A()'在那裏? – GhostCat

+0

@GhostCat我不明白爲什麼這個方法是通用的。它不應該是,它的返回類型應該是A.我意識到真正的情況可能更復雜,但我們對此一無所知。 –

+0

@JBNizet我已經更新了這個例子,使它更類似於真實案例(這仍然只是一個例子)。 –

1

你是對的,但只是一部分。 A或B是T,這是絕對正確的。但T本身不是A或B。例如。我有另一個類D和D擴展A.所以,D也是T。如果你說T是A,你也意味着D是A.這是不正確的,因爲D是A的子類型。