8

我目前正在編寫一個Java編譯器並已實現第15.12.2.7節。的JLS7(http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7),這是該規範中最令人討厭的部分之一。由於規範似乎沒有明確規定或含糊不清,我仍然有一個問題。我的問題是這條線:Java規範中的方法類型推斷

lcta(U)=?如果U的上界是Object,否則? (U,Object)

U是一個任意類型的表達式。類型表達式的上限是什麼?另外,爲什麼lcta總是通配符?

該規範定義

CandidateInvocation(G)= LCI(INV(G))。例如,現在考慮Inv(G)= {列表<字符串>}的情況,即唯一可能的候選調用是單個參數化類型。現在,由於該規則

LCI(G < X1,...,XN >)= G < LCTA(X1),...,LCTA(XN)>

的結果CandidateInvocation(G)= LCI({列表<字符串>})將被定義爲:

列表< LCTA(字符串)>

我認爲

,LCTA應簡體因爲如果列表<字符串>是唯一可能的調用,推斷列表<字符串>作爲參數是一個好主意。然而,lcta(U)的定義表明結果是?要麼 ?擴展了Iub(...),所以結果總是一個通配符。這似乎很奇怪。我在這裏誤解了什麼?

回答

1

我要求編譯器-dev郵件列表,並收到了答案:

是的,規格是錯在這裏。 lcta(U)的規則簡直就是徹頭徹尾的廢話:)。此外,他們聲稱,根本不用調用lcta(U)作爲單個參數並僅使用U(因爲單個參數U的最小公共類型參數應始終爲U本身)會更好。

6

這看起來像一個規範的錯誤。 JSL3中不存在lcta(U)的條款。顯然,當n=1時,JLS3的lci(e1..en)的定義不完整,新規格試圖修復它。但按照你的理由,修正看起來很亂。

Javac7計算lci({ List<String> })List<String>,忽略添加的子句。

這個問題應該提交給spec維護者;不知道如何與他們聯繫。你可以試試openjdk compiler-dev郵件列表;有一些知識淵博的人。

+0

我現在已經實施了lcta(U)= U這似乎工作正常。如果我發現任何這種實現產生令人驚訝的結果的情況,我會報告。順便說一句:不是lub(U,Object)總是U,因爲Object總是U的一個超類,因此{U,Object}的最小化擦除候選MEC應該總是產生U或它的一個子類?因此,這個規則真的很糟糕。唯一可能改善的是轉型嗎?將Object擴展到?但是,因爲U是一個類型表達式,所以它不能包含通配符,所以這種情況可能永遠不會發生......真的很奇怪。 – gexicide

+0

和郵件列表的好主意,我想我會試試看 – gexicide

+0

我認爲lub(U,Object)= Object – irreputable