为什么“迭代的数组实例”不能在Java中编译?

2022-09-03 06:31:28
Object[] array = new Object[]{};
System.out.println((array instanceof Serializable));//passed
System.out.println((array instanceof Cloneable));//passed

此代码编译并运行。输出为:

true
true

但是,此代码不会编译:

System.out.println((array instanceof Iterable));//not passed

Eclipse 编译器报告:

不兼容的条件操作数类型 对象[] 和可迭代

我发现数组只能在接口之间和使用操作时进行比较。有人能告诉我为什么吗?SerializableCloneableinstanceof


答案 1

根据 JLS,Java SE 7 版本,§15.20.2(类型比较运算符):instanceof

如果将 RelationalExpression 强制转换为 ReferenceType 作为编译时错误而被拒绝,则关系表达式同样会产生编译时错误。在这种情况下,表达式的结果永远不可能是真的。instanceofinstanceof

§15.16(强制转换表达式)规定:

如果根据强制转换转换规则 (§5.5) 永远不能将操作数的编译时类型强制转换为强制转换运算符指定的类型,则这是一个编译时错误。

最后,§5.5.1(参考类型转换)指出:

给定编译时引用类型 S(源)和编译时引用类型 T(目标),如果由于以下规则未发生编译时错误,则存在从 ST 的强制转换转换。

[...]

如果 SSC[] 类型的数组,即 SC 类型的组件数组:

  • 如果 T 是接口类型,则发生编译时错误,除非 T 是类型或类型(数组实现的唯一接口)。java.io.SerializableCloneable

因此,Java 要求测试以查看数组类型是否是编译时错误结果的实例。java.lang.Iterable

如果你想尝试让它工作(总是返回),你可以把数组投射到第一位,就像这样:falseObject

System.out.println((((Object)array) instanceof Iterable));

答案 2

您混淆了对象在 foreach 循环中使用的适用性,以及数组未实现的接口。Iterable

数组和可迭代都受 foreach 语法支持。

这并不意味着数组是可迭代的。