【发布时间】:2015-12-12 05:11:32
【问题描述】:
我在阅读 this article 关于“Java 中的奇怪事物”的内容时遇到了一个有趣的概念:不可确定的类型。
考虑以下三个类/接口:
public interface Type<T> { }
public class D<P> implements Type<Type<? super D<D<P>>>> { }
public class WildcardTest {
Type<? super D<Byte>> d = new D<Byte>();
}
显然问题在于D 是否是Type<? super D<Byte>> 是无法确定的;谁能进一步解释一下?
javac 1.8.0_60 在尝试编译 WildcardTest 时抛出一个很长的 StackOverflowError:
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4640)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3834)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3826)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:778)
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4640)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3839)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3826)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:778)
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4640)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3839)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3826)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:778)
at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4640)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3839)
at com.sun.tools.javac.code.Types$26.visitClassType(Types.java:3826)
at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:778)
此代码还会使整个 Eclipse IDE 崩溃。
作者提交了一个错误with the Eclipse team,但没有得到任何投票(除了我的)。有什么可以做的吗?这只是编译器形式的Halting Problem 吗?
【问题讨论】:
-
显然,它是a known bug(从 2007 年开始!)计划在 Java 9 中修复。
-
我本来打算参考“驯服通配符”,但它已经被文章链接了,我认为我们没有人能比论文更好地解释。另外,论文没有说它是否是不可判定的。
-
@durron597 - 我不能假装我理解这个问题:) 我能理解这个困难。想想一个更简单的问题——supertypes of Integer 是什么?
-
JLS 通过直接超类型定义子类型。但我不清楚直接超类型集是如何定义的,当它是递归的时候。
-
@Powerlord - 这正是通配符通常使用的地方:) - 作为变量类型。 (当你调用带有通配符参数的方法时,相当于将参数分配给参数)
标签: java generics types compilation stack-overflow