2011-04-17 28 views
0

有三個Java 1.6接口繼承一個從另一個:如何在界面中使返回類型泛型?

interface First<T extends First<T>> { 
    T me(); 
} 
interface Second<T extends Second<T>> extends First<T> { 
} 
interface Third<T extends Third<T>> extends Second<T> { 
    void foo(); 
} 

現在我很期待這一個工作,但沒有:

// somewhere later 
public void bar(Third t) { 
    t.me().foo(); 
} 

編譯器說,t.me()Second類型。我究竟做錯了什麼?

+1

當我嘗試它時,編譯器似乎認爲t.me()是第一種類型! – 2011-04-17 12:32:47

+0

@Tom更糟。你知道如何讓編譯器認爲't.me()'是'Third'類型嗎? – yegor256 2011-04-17 12:36:48

+1

正如BeyoncéKnowles所說(稍微解釋一下),如果你想使用它,你應該在其上放置一個類型參數。 – 2011-04-17 12:40:59

回答

1

試試這個:

public <T extends Third<T>> void bar(Third<T> t) { 
    t.me().foo(); 
} 
+0

可否請您再次查看我的問題,最後我進行了更正。我無法控制't'的實例化。這對我來說是'Third'的類型。 – yegor256 2011-04-17 12:35:46

+0

@yegor:看到我更新的答案。 – 2011-04-17 12:40:16

1

的問題是,你有沒有在T的聲明,這使得原始類型提供的類型參數。所有關於泛型的推理都因此失去作用。因爲me()被聲明爲返回T中的類型T,所以用T extends First進行參數化,其原始類型爲First,這就是編譯器將它視爲即使它來自Third的情況。

如果你要提供一個參數給任何值的t - ! - 編譯器將能夠使用關於泛型的規則,並且可以計算出me()返回第三個。例如,像Oli建議的那樣寫一些Foo類的話會做到這一點,就像將它綁定到?一樣。

如果將第三個實例作爲原始類型的變量,則將其分配給類型爲Third的變量。這是合法的,從來沒有檢查過,並會讓你覺得你應該在哪裏。