编译器构造为什么这是无效的Java?三值运算符输出类型
看看这个代码
// 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
}
我知道怎么解决。我只是想知道为什么会这样。编译器不应该简单地检查所有可能的输出吗
# 1 楼答案
在这种情况下,条件表达式具有两种类型中最小上界的类型,即
Object
,而foreach循环不适用于Object
# 2 楼答案
表达式
(i2 == null) ? i1 : i2
的静态结果类型是对象i1
和i2
的共同祖先。for
语句要求表达式的静态类型为Iterable
或数组类型。事实并非如此,因此会出现编译错误现在,如果你问为什么编译器不推断
(i2 == null) ? i1 : i2
总是一个数组或一个Iterable:假设,如果Java类型的系统有点不同,那么这个特殊的情况可以得到更好的处理。具体来说,如果Java支持algebraic data types,那么可以将
o
声明为“对象数组或iterable”。。。而且for
循环是可检查类型的1-假设
o
已初始化为o = (x * x < 0) ? new Object() : new Object[0]
。要确定这总是会导致Object[]
实例,需要一个小证明,证明(实数)的平方不是负的。这是一个简单的例子,可以构造任意复杂的例子,需要任意困难的证明2-数学证明停顿问题是一个不可数函数。换句话说,存在数学上无法证明它们是否终止的函数