在Java字节码程序集指令级别上钻入操作符instanceof时,它对应于instanceof程序集指令。但我读过以前的规则
确定非null的objectref是否为已解析类型的实例:
第二条规则规定:
如果S是一个接口类型,那么:
这让我很困惑。"S是接口类型“是指S的引用类型是接口类型吗?如果是这样,第一个规则“如果T是一个类类型,那么T必须是一个对象”不能成立。例如,
CharSequence charSequence = new StringBuilder("test");
System.out.println(charSequence instanceof StringBuilder);
System.out.println(charSequence instanceof String);上面代码中的第二行将打印true,而上面的第三行将打印false。所以我怀疑我的理解可能是错的,谁能帮我解释一下上面规则的含义?
发布于 2017-08-07 12:28:39
你有权感到困惑,因为这些规则的写作方式令人困惑。
对于对象来说,不可能有一个接口类型,因为每个实例化对象都有一个实际的、非抽象的类型,可能是实现了一个接口。这甚至适用于为lambda表达式生成的实例,这些表达式具有实现函数接口的未指定(匿名)类型。
所以乍一看,这些规则的这一部分似乎毫无意义。但请考虑全文:
以下规则用于确定非
null的对象是否为已解析类型的实例:如果S是objectref所引用的对象的类,而T是已解析的类、数组或接口类型,instanceof将确定对象是否为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类型的组件数组,那么以下内容之一必须为真:TC和SC是相同的原语类型。TC和SC是引用类型,可以通过这些运行时规则将类型SC转换为TC。由于objectref引用的实际对象不可能具有接口类型,因此只应用另外两个符号;它的类型要么是“普通(非数组)类”,要么是数组类型。在后一种情况下,最后一句是有趣的,因为它指的是作为一个整体引用的规则,如果两者都是引用类型的数组,则应用于T和S的组件类型。组件类型可以是接口类型。
因此,可以使用接口类型的实际数组实例来测试这些规则,并对照其他数组类型进行检查:
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它认为,如果接口大小写是在数组特例中描述的,那么它就不会那么混乱了。另一方面,这三种情况都遵循一般的正式分配规则,因此在这种形式下更容易被识别。
https://stackoverflow.com/questions/45507276
复制相似问题