16
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 编译器报告:

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

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

4

4 回答 4

15

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

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

并且 § 15.16 (Cast Expressions) 规定:

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

最后,第5.5.1节(引用类型转换)指出:

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

[...]

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

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

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

如果你想尝试让它工作(总是 return false),你可以将数组转换为Objectfirst ,如下所示:

System.out.println((((Object)array) instanceof Iterable));
于 2012-07-06T02:30:48.063 回答
5

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

foreach 语法支持数组和 Iterable。

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

于 2012-07-06T02:13:42.397 回答
0

我猜是因为两者Serializable都是Cloneable标记接口,而 asIterable不是。

于 2012-07-06T02:26:59.200 回答
0

因为java是一种静态语言,所以编译器知道数组不会Iterable在编译时出现,编译器知道这array instanceof Iterable永远不会是真的,所以它会触发编译时错误来警告你。

于 2012-07-06T02:35:02.620 回答