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

时间:2012-07-06 02:08:28

标签: java arrays compiler-errors

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时,只能在接口Cloneableinstanceof之间比较数组。有人可以告诉我为什么吗?

4 个答案:

答案 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)

我猜是因为SerializableCloneable都是标记接口,Iterable不是。

答案 3 :(得分:0)

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