8

我目前正在编写 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 总是通配符?

规范定义

候选调用(G)= lci(Inv(G))

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

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

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

列表<lcta(String)>

在我看来,lcta 应该在这里简单地返回 String,因为如果 List<String> 是唯一可能的调用,那么推断 List<String> 作为参数是个好主意。但是,lcta(U) 的定义表明结果是 ? 或者 ?扩展 lub(...),所以结果总是一个通配符。这似乎很奇怪。我在这里误解了什么?

4

2 回答 2

6

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

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

这个问题应该向规范维护者提出;不知道如何联系他们。你可以试试 openjdk编译器开发邮件列表;上面有一些知识渊博的人。

于 2012-05-21T21:09:23.807 回答
1

我在编译器开发邮件列表中询问并收到了答案:

是的,这里的规范是错误的。lcta(U) 的规则完全是废话:)。此外,他们声称最好不要为单个参数调用 lcta(U) 而只使用 U(因为单个参数 U 的最不常见的类型参数应该始终是 U 本身)。

于 2012-06-15T10:23:18.850 回答