Dan*_*iel 11 java programming-languages type-inference wildcard
JLS在类型推断算法(第15.12.2节)中提到:
上述过程有可能产生无限类型.这是允许的,Java编译器必须识别这种情况并使用循环数据结构恰当地表示它们.
但是,我无法找到javac生成无限类型的实际示例.我认为在下列情况下应该产生一个:
<T> T pick(T a, T b) { ... }
pick("string", 3);
Run Code Online (Sandbox Code Playgroud)
String和Integer都是Comparable <themselve>,因此它们的常用超类型应该是Comparable<? extends Comparable<? extends Comparable<? ...>>>(无限的).
我可以:
Comparable<? extends Comparable<?>> x = pick("string", 3);
Run Code Online (Sandbox Code Playgroud)
但后来我试过了:
Comparable<? extends Comparable<? extends Comparable<?>>> x = pick("string", 3);
Run Code Online (Sandbox Code Playgroud)
这不编译.似乎递归在两个步骤后中止.
您是否知道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)>
Run Code Online (Sandbox Code Playgroud)
所以lub(String, Integer)应该是无限型.Javac似乎在这里错了.也许它毕竟没有实现无限类型?
以下代码将javac发送到无限循环.据推测,它试图构建一个无限类型,但不能将其表示为有限循环数据结构.
interface I<T> {}
interface A<T> extends I<A<A<T>>>{}
abstract class X {
abstract <T> T foo(T x, T y);
void bar(A<Integer> x, A<String> y){
foo(x, y);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
653 次 |
| 最近记录: |