【发布时间】:2010-08-10 17:08:20
【问题描述】:
JLS 在类型推断算法(§15.12.2)中提到:
上面的过程有可能产生一个无限类型。这是允许的, Java 编译器必须识别这种情况并使用循环数据结构适当地表示它们。
但是,我找不到 javac 生成无限类型的实际示例。 我认为它应该在以下情况下产生一个:
<T> T pick(T a, T b) { ... }
pick("string", 3);
String 和 Integer 都是 ComparableComparable<? extends Comparable<? extends Comparable<? ...>>>(无限)。
我能做到:
Comparable<? extends Comparable<?>> x = pick("string", 3);
但后来我尝试了:
Comparable<? extends Comparable<? extends Comparable<?>>> x = pick("string", 3);
这不会编译。 似乎递归在 2 步后中止了。
你知道有什么情况可以让 Java 实际上产生一个无限类型吗?
--
编辑:上面似乎是一个编译器错误。阅读规范,让我们看看lub(String, Integer) 的计算结果如何:
ST(String) = { String, Comparable<String>, Serializable, CharSequence, Object }
ST(Integer) = { Integer, Comparable<Integer>, Serializable, Number, Object }
EC = { Comparable, Serializable, Object }
MEC = { Comparable, Serializable }
Inv(Comparable) = { Comparable<String>, Comparable<Integer> }
lcta(String, Integer) = ? extends lub(String, Integer)
lci(Inv(Comparable)) = Comparable<? extends lub(String, Integer)>
lub(String, Integer) = Serializable & Comparable<? extends lub(String, Integer)>
所以lub(String, Integer) 应该是一个无限类型。 Javac 在这里似乎是错误的。也许它毕竟没有实现无限类型?
【问题讨论】:
-
请记住您引用的最后一部分:“...Java 编译器必须识别这种情况并适当地表示它们...”。如果你给它一个“无限类型”,任何符合规范的编译器都不会闪烁。将类型擦除添加到混合中,示例中的所有内容都会变成 Comparable 或 Object。因此,除非您正在构建 Java 编译器,否则您可能永远都不会注意到。
-
@cHao:看起来 Sun 的 javac 不符合规范。我无法用它产生任何无限类型,这就是我问这个问题的原因。似乎他们只是未实现此语言功能。
标签: java programming-languages wildcard type-inference