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
我发现在使用操作Serializable
时,只能在接口Cloneable
和instanceof
之间比较数组。有人可以告诉我为什么吗?
答案 0 :(得分:15)
根据JLS, Java SE 7 edition,§15.20.2(类型比较运算符instanceof
):
如果将 RelationalExpression 转换为 ReferenceType 作为 编译时错误,然后
instanceof
关系表达式同样产生 编译时错误。在这种情况下,instanceof
表达式的结果 永远不会是真的。
§15.16(演员表达)声明:
如果操作数的编译时类型可能永远不会是编译时错误 根据强制转换规则强制转换为强制转换运算符指定的类型 转换(§5.5)。
最后,§5.5.1(参考类型转换)声明:
给定编译时引用类型 S (源)和编译时引用类型 T (目标),如果没有发生编译时错误,则从 S 到 T 存在转换转换 由于以下规则。
[...]
如果 S 是数组类型 SC [],即 SC 类型的组件数组:
- 如果 T 是接口类型,则会发生编译时错误,除非 T 是类型
java.io.Serializable
或类型Cloneable
(实现的唯一接口 数组)。
因此,Java 要求您的测试以查看数组类型是否为java.lang.Iterable
的实例会导致编译时错误。
如果你想尝试使其工作(总是返回false
),你可以先将数组转换为Object
,如下所示:
System.out.println((((Object)array) instanceof Iterable));
答案 1 :(得分:5)
对于在foreach循环中使用的对象以及Iterable
接口(数组未实现的接口)的混淆,你会感到困惑。
foreach语法支持数组和Iterable。
这并不意味着数组是可迭代的。
答案 2 :(得分:0)
我猜是因为Serializable
和Cloneable
都是标记接口,Iterable
不是。
答案 3 :(得分:0)
因为java是一种静态语言,所以编译器知道数组在编译时不会是Iterable
,编译器知道array instanceof Iterable
永远不会是真的,所以它会触发编译时错误警告你。