2017-08-04 33 views
3

当在Java字节码汇编指令级别下钻到运算符instanceof时,它对应于Java汇编指令instanceof。不过,我看到用于Java组装指令instanceof的规则是什么意思?

规则确定objectref非空是否是解决类型的实例:

第二条规则说:

如果S是一个接口类型,则:

  • 如果T是类类型,那么T必须是Object。
  • 如果T是一个接口类型,则T必须是相同的接口S或S.
  • 的超接口

这使我感到困惑。 “S是接口类型”是指S的引用类型是接口类型吗?如果是这样,第一条规则“如果T是一个类的类型,那么T必须是一个对象”不能成立。例如,

CharSequence charSequence = new StringBuilder("test"); 
System.out.println(charSequence instanceof StringBuilder); 
System.out.println(charSequence instanceof String); 

上面的代码中的第二行将打印为true,而上面的第三行将打印为false。所以我怀疑我的理解可能是错误的,任何人都可以帮助解释上述规则的含义?

+0

'S是由* objectref *'引用的对象的类:在这种情况下,'StringBuilder'。第三行打印“false”是正确的。 – EJP

+0

@EJP但是你不觉得我提到的第一条规则与我给出的代码打印的规则不同吗?字符串是对象,是不是 – Rui

回答

2

您有权混淆,因为这些规则的编写方式,都是混淆。

对于objectref,它是不可能具有一个接口类型,因为每一个实例化的对象具有实际的,非抽象类型,或许实现接口。这甚至适用于为lambda表达式生成的实例,该实例具有实现功能接口的未指定(匿名)类型。

因此,乍一看,这些规则的这部分似乎没有意义。但考虑到全文:

以下规则来确定objectref不是null是否是解决类型的实例:如果Sobjectref引用的类的对象并T是决定的类,数组或接口类型,的instanceof确定objectref是否是T一个实例如下:

  • 如果S是一个普通的(非数组)类,则:
    • 如果T是一个类型,那么S必须是相同的类作为T,或S必须是T的子类;
    • 如果T是接口类型,则S必须实现接口T
  • 如果S是一个接口类型,那么:
    • 如果T是一个类型,那么T必须是对象。
    • 如果T是接口类型,则T必须与S相同的接口或S的超级接口。
  • 如果S是表示阵列型SC[]一个类,也就是说,SC类型的元件的阵列,则:
    • 如果T是一个类型,那么T必须是对象。
    • 如果T是接口类型,那么T必须是由数组(JLS§4.10.3)实现的接口之一。
    • 如果T是数组类型TC[],即,TC类型的元件的阵列,则必须满足以下条件之一:
      • TCSC是相同的基本类型。
      • TCSC是参考类型,并且类型SC可以通过这些运行时规则转换为TC

由于不可能通过objectref参考具有一个接口类型的实际对象,只有其他两个子弹适用;它的类型是“普通(非数组)类”或数组类型。在后一种情况下,如果两个引用类型都是引用类型的数组,则最后一句是有趣的,因为它引用了整个引用的规则,适用于组件类型TS。组件类型可以是接口类型。

所以,你可以使用一个接口类型的实际数组实例测试这些规则,检查,对其他数组类型:

Object o = new Collection[0]; // SC is Collection 
System.out.println(o instanceof Object[]); // TC is class type Object -> true 
System.out.println(o instanceof String[]); // TC is class type other than Object -> false 
System.out.println(o instanceof Collection[]); // TC == SC -> true 
System.out.println(o instanceof Iterable[]); // TC is super interface of SC -> true 
System.out.println(o instanceof List[]); // TC is not super interface SC -> false 

据认为,这将是减少混乱,如果接口案件中所描述的数组特殊情况下,它可能适用。另一方面,这三种情况遵循一般的正式分配规则,因此在这种形式下更容易识别。

+0

所以这只会工作,因为数组是协变的权利?我想不出一个地方,我已经看到一个isntanceOf对数组,虽然 – Eugene

+0

@Eugene:这是*使*阵列协变的规则之一。 – Holger