And*_*lla 2 java compiler-construction iterator ternary-operator
看看这段代码.
// Print object and recurse if iterable
private static void deep_print(Object o) {
System.out.println(o.getClass().toString() + ", " + o.toString());
boolean iter = false;
Iterable<?> i1 = null;
Object[] i2 = null;
if (o instanceof Iterable<?>) {
iter = true;
i1 = (Iterable<?>) o;
} else if (o instanceof Object[]) {
iter = true;
i2 = (Object[]) o;
}
if (iter) {
for (Object o_ : i2 == null ? i1 : i2) deep_print(o_); // ERROR: Can only iterate over an array or an instance of java.lang.Iterable
}
Run Code Online (Sandbox Code Playgroud)
我知道如何解决它.我只想知道它为什么会发生.编译器不应该只检查所有可能的输出吗?
表达的静态结果类型(i2 == null) ? i1 : i2是共同的祖先i1和i2哪个是对象.甲for语句需要的静态类型表达的是任一种Iterable或阵列型.情况并非如此,因此您会收到编译错误.
现在,如果你问为什么编译器不会推断出(i2 == null) ? i1 : i2总是数组或Iterable:
假设,如果Java类型系统有点不同,则可以更好地处理这种特殊情况.具体来说,如果Java支持代数数据类型,则可以将其声明o为"对象数组或可迭代"......并且for循环可以是类型可检查的.
1 - 假设o已初始化为o = (x * x < 0) ? new Object() : new Object[0].确定总是会导致Object[]实例的实例需要一个小证明,其中涉及(实数)的平方不是负数的事实.这是一个简单的例子,可以构造任意复杂的例子,需要任意的难以证明.
2 - 停止问题在数学上被证明是一个不可计算的函数.换句话说,存在这样的功能,即在数学上不可能证明它们是否终止.