gpt4 book ai didi

java - 为什么这是无效的 Java?三元运算符输出的类型

转载 作者:行者123 更新时间:2023-12-02 15:44:57 24 4
gpt4 key购买 nike

查看此代码。

// 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
}

我知道怎么解决了。我只是想知道为什么会这样。编译器不应该简单地检查所有可能的输出吗?

最佳答案

表达式 (i2 == null) ? i1 : i2 的静态结果类型是 i1 的共同祖先和i2这是对象。一个for语句要求表达式的静态类型Iterable或数组类型。情况并非如此,因此您会收到编译错误。

现在,如果您问为什么编译器不推断出 (i2 == null) ? i1 : i2将始终是一个数组或一个 Iterable:

  1. Java 语言规范 (JLS) 不允许这样做。
  2. 如果 JLS 确实允许(但不要求),那么不同的编译器会有不同的行为,具体取决于它们在定理证明方面的表现。不好。
  3. 如果 JLS 需要它,那么编译器必须合并复杂的定理证明器`1(速度很慢),并且您会遇到解决停止问题的“轻微不便” 2(坏坏坏)。
  4. 事实上,编译器需要知道表达式属于两种类型中的哪一种,因为它需要在每种情况下生成不同的代码。
<小时/>

假设,如果 Java 类型系统有点不同,这种特殊情况可以得到更好的处理。具体来说,如果Java支持algebraic data types那么就可以声明 o作为“对象数组或可迭代对象”...以及 for循环可以进行类型检查。

<小时/>

1 - 假设 o已初始化为 o = (x * x < 0) ? new Object() : new Object[0] 。确定这将始终导致 Object[]实例需要一个小证明,涉及一个(实数)数的平方不为负的事实。这是一个简单的例子,可以构造任意复杂的例子,需要任意困难的证明。

2 - 停止问题在数学上被证明是一个不可计算的函数。换句话说,存在一些函数,在数学上无法证明它们是否终止。

关于java - 为什么这是无效的 Java?三元运算符输出的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1291655/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com