2017-04-10 73 views
2

讓我們從一個代碼示例開始,理想情況下,我希望可以這樣做。Java泛型,在C <T extends MyClass <Z>>中,方法應返回Z

由於MyOtherClass是一個通用的

class MyOtherClass<Z>{} 

我想獲得的MyOtherClass

class C<T extends MyOtherClass<Z>> { 
    Z myTypeOfReturnMethod() { return doStuff(); } 
} 

在Z不幸的是,據我知道,我不能指定,唯一有效的語法會be

class C<T extends MyOtherClass> { 
    ???MyOtherClass.Z??? myTypeOfReturnMethod() { return doStuff(); } 
} 

這樣做的最好方法是什麼? C可能有兩種泛型,但它是重複性和容易出錯的。

回答

3

「簡單」的解決方案是通過明確引入它像這樣講述的附加型約束的Java:

class C<Z, T extends MyOtherClass<Z>> { 
    // ... 
} 

雖然這意味着一些人可以在你的typedeclarations感知爲冗餘的,至少你居然得到你想要的東西...

其他所有的東西在語義上都不被Java支持,主要是因爲你在TypeBound of T中的Z不能作爲Type參數(在JLS 8.1.2的意義上)被訪問,但是TypeBound 。您想使用Z的地方還不知道Z,因爲這並未作爲類型參數清晰地引入並被清除。即使myTypeOfReturnMethod的簽名更改爲Object時也會發生編譯錯誤,這一點尤其證明了這一點。其結果仍然是:

error: cannot find symbol 
    class C<T extends MyOtherClass<Z>> { 
           ^
symbol: class Z 

除了你最有可能真正想要的東西是什麼「更冗餘」(咳嗽),即:

class C<Z, T extends MyOtherClass<? extends Z>> { 

這實際上是由於在相當一些SO問題和JLS中列出的原因,與上面的非常不同...

+2

我不明白爲什麼這會是多餘的。 – shmosel

+0

@shmosel調整公式並增加了一些信息;) – Vogel612

+3

仍然不認爲它是非常多餘的。我不會推薦'?擴展Z',除非明確指出'Z'是(僅)生產者,按[PECS](http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super)。 – shmosel

相關問題