为什么不在Java中编译"array instanceof Iterable"?

ohy*_*zai 16 java arrays compiler-errors

Object[] array = new Object[]{};
System.out.println((array instanceof Serializable));//passed
System.out.println((array instanceof Cloneable));//passed
Run Code Online (Sandbox Code Playgroud)

此代码编译并运行.输出是:

true
true
Run Code Online (Sandbox Code Playgroud)

但是,此代码无法编译:

System.out.println((array instanceof Iterable));//not passed
Run Code Online (Sandbox Code Playgroud)

Eclipse编译器报告:

不兼容的条件操作数类型Object []和Iterable

我发现只能在接口SerializableCloneable使用操作之间比较数组instanceof.有人可以告诉我为什么吗?

Jon*_*len 15

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

如果将RelationalExpression转换为ReferenceType将作为编译时错误被拒绝,则instanceof关系表达式同样会产生编译时错误.在这种情况下,instanceof表达式的结果永远不会成立.

和第15.16(转换表达式)规定:

如果操作数的编译时类型永远不会根据强制转换规则(第5.5节)强制转换为强制转换运算符指定的类型,那么这是一个编译时错误.

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

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

[...]

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

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

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

如果你想尝试使其工作(总是返回false),你可以将数组转换为Object第一个,如下所示:

System.out.println((((Object)array) instanceof Iterable));
Run Code Online (Sandbox Code Playgroud)


Boh*_*ian 5

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

foreach语法支持数组和Iterable.

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

  • 不,问题不是数组不可迭代的原因; 这就是编译器认为该行不被认为是有效Java的原因. (2认同)