2011-03-05 92 views
6

根據Java泛型常見問題 http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 類型參數不能用這種方式在Java的泛型類型參數的正向參考

<A extends B, B> // error 

向前引用,但它是確定有

<A extends List<B>, B> // ok 

這兩個示例已通過最新的jdk 1.6.0_24進行驗證。

我的問題是,在語言規範中,這是指定的,隱含的或可抵扣的(即如果它不真實,其他事情可能會炸燬)。我無法在任何地方找到它。

更新

在javac7,它是允許的。直觀地說,類型參數的順序並不重要;類型系統要求類型變量之間不存在循環依賴關係:<A extends B, B extends A>。以前,這可以通過禁止前向引用來保證。顯然,javac 7被改進以放寬排序,同時檢測週期而不管排序。

+0

所以看起來,這個規則是由java泛型傢伙熟知的,但他們忘了把它放在語言規範中。 – irreputable 2011-03-20 03:11:16

回答

3

我不確定這是真的。我看着在Java Language Specification和§ 6.3有類型參數的範圍的討論:

接口的類型參數的範圍是包括類型參數部分本身接口的整個聲明。因此,類型參數可以作爲它們自己的邊界的一部分出現,也可以作爲在同一節中聲明的其他類型參數的邊界出現。

方法的類型參數的範圍是該方法的整個聲明,包括類型參數部分本身。因此,類型參數可以作爲它們自己的邊界的一部分出現,也可以作爲在同一節中聲明的其他類型參數的邊界出現。

構造函數的類型參數的範圍是構造函數的整個聲明,包括類型參數部分本身。因此,類型參數可以作爲它們自己的邊界的一部分出現,也可以作爲在同一節中聲明的其他類型參數的邊界出現。

(我的重點)。

這表明,在聲明

B確實是在範圍寫A extends B時。

此外,§ 4。所述JLS的4說,指的是結合在一種類型的變量時,即

結合的方案包括將類型變量,或一個類或接口類型T

這表明的不僅在<A extends B, B>的範圍內,而且它在A上是完全合法的界限。

最後,頂部東西了,這個代碼編譯在javac

public class Test { 
    public static <A extends B, B> A test(B obj) { 
     return null; 
    } 
} 

所以我敢肯定,這是完全合法的Java代碼以及您鏈接到的例子或者是錯誤的或指的是別的東西。

希望這會有所幫助,並讓我知道我的推理是否存在缺陷!

+0

但它不能在我的javac1.6 u21 b06中編譯。 「非法前向參考」 – irreputable 2011-03-05 09:52:30

+0

@ unreputationable-嗯,這真的很奇怪。我誤解了我引用的JLS的相關部分嗎?或者你的'javac'實現中有錯誤嗎? – templatetypedef 2011-03-05 09:57:25

+0

你的javac是什麼版本? – irreputable 2011-03-05 10:05:27

0

這是完全合法的,也就是說,你可以想象,A擴展了C,它通常擴展爲B. 那麼當C擴展B時,你會怎麼說?