Java规范中的方法类型推断

时间:2012-05-21 19:01:53

标签: java compiler-construction type-inference specifications

我目前正在编写Java编译器并已实现了第15.12.2.7节。 JLS7(http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7),这是规范中最讨厌的部分之一。我仍然有一个问题,因为规范似乎不明确或模棱两可。我的问题是这一行:

lcta(U)=?如果U的上限是Object,否则?扩展lub(U,Object)

U是任意类型的表达式。类型表达式的上限是多少?另外,为什么lcta总是一个通配符?

规范定义

CandidateInvocation(G)= lci(Inv(G))

现在,例如,考虑Inv(G)= {List< String> ,即,唯一可能的候选调用是单个参数化类型。现在,由于规则

lci(G< X1,...,Xn>)= G< lcta(X1),...,lcta(Xn)>

CandidateInvocation(G)=的结果 lci({List< String>})将被定义为:

列表与LT; LCTA(字符串)>

在我看来,lcta应该只是在这里返回String,因为如果List< String>是唯一可能的调用,推断List< String>是个好主意。作为论点。但是,lcta(U)的定义要求结果是?要么 ?扩展lub(...),因此结果始终是通配符。这看起来很奇怪。我在这里误解了什么?

2 个答案:

答案 0 :(得分:6)

这看起来像规范的错误。 JSL3中不存在lcta(U)的子句。显然,lci(e1..en)时JLS3对n=1的定义不完整,新规范试图修复它。但正如你所推断的那样,修复似乎是胡言乱语。

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

这个问题应该提到规范维护者;不知道如何联系他们。您可以尝试使用openjdk compiler-dev 邮件列表;有一些知识渊博的人。

答案 1 :(得分:1)

我已经在compiler-dev邮件列表中询问并收到了答案:

是的,这里的规范是错误的。 lcta(U)的规则只是完全废话:)。此外,他们声称最好不要为一个参数调用lcta(U)并且只使用U(因为单个参数U的最小公共类型参数应该总是U本身)。