JLS在类型推断算法(第15.12.2节)中提到:
上述过程可能会产生无限类型。这是允许的, Java编译器必须识别这种情况并使用循环数据结构恰当地表示它们。
但是,我无法找到javac生成无限类型的实际示例。 我认为在下列情况下应该产生一个:
<T> T pick(T a, T b) { ... }
pick("string", 3);
String和Integer都是Comparable&lt; themselve&gt;,所以它们的常用超类型应该是Comparable<? extends Comparable<? extends Comparable<? ...>>>
(无限)。
我能做到:
Comparable<? extends Comparable<?>> x = pick("string", 3);
然后我尝试了:
Comparable<? extends Comparable<? extends Comparable<?>>> x = pick("string", 3);
这不会编译。 似乎递归在两个步骤后中止。
你知道任何使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似乎在这里错了。也许它毕竟没有实现无限类型?
答案 0 :(得分:9)
以下代码将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);
}
}
答案 1 :(得分:0)
R.Grigore(2016)在他的论文 Java Generics Turing Complete
中回答了这个问题。以下面的Java代码作为他的建议的示例:
//an empty interface
interface Z {}
//4 generic interfaces, one argument each
interface N<X> {}
interface L<X> {}
interface Qlr<X> {}
interface Qrl<X> {}
//one complex generic, inheriting from instantiations of two other
interface E<X> extends
Qlr<N<? super Qr<? super E<? super E<? super X>>>>>,
Qrl<N<?super Ql<? super E<? super E<? super X>>>>>
{}
//main class with a single function
class Main{
//heavily nested return type
L<? super N<? super L<? super N<? super L<? super N<? super E<? super E<? super Z>>>>>>>>
f(Qr<? super E<? super E<? super Z>>> v) {return v;}
}
答案 2 :(得分:-1)
无限类型的可能性可能是(例如,地图内地图内的Map对象等等......
Map<? extends Serializable, Map<? extends Serializable, Map<? extends Serializable, Map<? extends Serializable, Map<? extends Serializable, Map>>>>> objectMap;
(为了便于阅读,这是为了深度5 ...但您可以在地图中无限深地添加地图。
我不知道这是不是你要找的......