Java里面instanceof怎么实现的
开始完全一头雾水呀,后面看了Java指令集的介绍,逐渐理解了。
https://www.zhihu.com/question/21574535/answer/18998914
下面这个答案比较直白
你在面月薪10000的Java高级研发职位。面试官对JVM有一些了解,想让你说说JVM会如何实现 instanceof 指令。
但他可能也没看过实际的JVM是怎么做的,只是臆想过一下而已。JVM的规定就是“底层”。这种情况就给他JVM规范对 instanceof 指令的定义就好:
Chapter 6. The Java Virtual Machine Instruction Set, JVM规范Java SE 7版
根据规范来臆想一下实现就能八九不离十的混过这题了。 地址:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.instanceof
上面指令的定义详细解释如下(解释和重要点已经飘红指出):
instanceof
Operation
Determine if object is of given type
Format
instanceof
indexbyte1
indexbyte2
Forms
instanceof = 193 (0xc1)
Operand Stack
..., objectref →
..., result
Description
The objectref, which must be of type reference, is popped from the operand stack. The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (§2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool item at the index must be a symbolic reference to a class, array, or interface type.
If objectref is null, the instanceof instruction pushes an int result of 0 as an int on the operand stack.
意思是左侧是null,就返回false.(另外,右侧不能为null)
Otherwise, the named class, array, or interface type is resolved (§5.4.3.1). If objectref is an instance of the resolved class or array or implements the resolved interface, the instanceof instruction pushes an int result of 1 as an int on the operand stack; otherwise, it pushes an int result of 0.
这个只是概述,下面是详细解释。分为多钟情况。
The following rules are used to determine whether an objectref that is not null is an instance of the resolved type: If S is the class of the object referred to by objectref and T is the resolved class, array, or interface type, instanceof determines whether objectref is an instance of T as follows:
If S is an ordinary (nonarray) class, then:
If T is a class type, then S must be the same class as T, or S must be a subclass of T;
If T is an interface type, then S must implement interface T.
If S is an interface type, then:
If T is a class type, then T must be
Object.If T is an interface type, then T must be the same interface as S or a superinterface of S.
If S is a class representing the array type SC
[], that is, an array of components of type SC, then:If T is a class type, then T must be
Object.If T is an interface type, then T must be one of the interfaces implemented by arrays (JLS §4.10.3).
If T is an array type TC
[], that is, an array of components of type TC, then one of the following must be true:TC and SC are the same primitive type.
TC and SC are reference types, and type SC can be cast to TC by these run-time rules.
Linking Exceptions
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §5.4.3.1 can be thrown.
Notes
The instanceof instruction is very similar to the checkcast instruction (§checkcast). It differs in its treatment of null(上面提到,左侧null会直接返回false), its behavior when its test fails (checkcast throws an exception, instanceof pushes a result code), and its effect on the operand stack.
下面这个答案比较“晦涩”
你在面试月薪10000以上的Java资深研发职位,注重性能调优啥的。这种职位虽然不直接涉及JVM的研发,但由于性能问题经常源自“抽象泄漏”,
对实际使用的JVM的实现的思路需要有所了解。面试官对JVM的了解可能也就在此程度。
对付这个可以用一篇论文:Fast subtype checking in the HotSpot JVM。
之前有个讨论帖里讨论过对这篇论文的解读:请教一个share/vm/oops下的代码做fast subtype check的问题 其中提到了 “抽象泄露”,后面会单开文章分析。
再看下面的代码例子(http://jurisp.iteye.com/blog/815704)
String s = null;
System.out.println(s instanceof Object); // false System.out.println(s instanceof String); // false // 下面的不能通过编译 Incompatible conditional operand types String and String[]
// boolean as = (s instanceof String[]); // 不能编译 Syntax error on token "null", invalid ReferenceType
// System.out.println(s instanceof null); // 不能编译 Incompatible conditional operand types TypeInstanceTest and String//System.out.println(new Solution() instanceof String); System.out.println(new String() instanceof String); //true System.out.println(new String() instanceof Object); //true // 会抛出异常
Solution test = (Solution) new Object();
而运行结果如下:
false
false
true
true
Exception
说明不是随便两个类型之间都能用instanceof的,如果两个操作数的类型都是类,其中一个必须是另一个的子类型。
另外,注意下面这段晦涩的表述。
访问静态方法,使用表达式作为限定符。表达式的值所引用的对象的运行期类型在确定哪一个方法被调用的时候不起作用,而且对象有标识符,其标识符也不起任何作用。
代码示例如下:
class Solution {
public static boolean canFinish() {
System.out.println("here");
return true;
}
public static void main(String[] args) {
((Solution) null).canFinish();
}
}
运行得到正确调用结果:
here
说明,用null是可以调用 static 方法的。
Java里面instanceof怎么实现的的更多相关文章
- java中instanceof和getClass()的作用
初学者难免有点混淆java中instanceof和getClass()的作用, 下面就来一一讲解. 父类A: class A { } 子类B: class B extends A { } 构造对象 ...
- 深入Java关键字instanceof
深入Java关键字instanceof instanceof关键字用于判断一个引用类型变量所指向的对象是否是一个类(或接口.抽象类.父类)的实例. 举个例子: public interface ...
- Java-Runoob-高级教程-实例-方法:07. Java 实例 – instanceOf 关键字用法
ylbtech-Java-Runoob-高级教程-实例-方法:07. Java 实例 – instanceOf 关键字用法 1.返回顶部 1. Java 实例 - instanceof 关键字用法 ...
- Java关键字instanceof
深入Java关键字instanceof instanceof关键字用于判断一个引用类型变量所指向的对象是否是一个类(或接口.抽象类.父类)的实例. 举个例子: public interfa ...
- Java中instanceof和isInstance的具体区别
Java中instanceof和isInstance的具体区别 在Think in Java泛型这一章遇到这个问题,一些博客模糊提到了isInstance是instanceof的动态实现,查阅文档参考 ...
- Java 实例 - instanceof 关键字用法
Java 实例 - instanceof 关键字用法 instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符. instanceof 是 Java 的保留关键 ...
- Java关键字——instanceof
Java中可以使用instanceof关键字判断一个对象到底是哪一个类的实例 格式:对象 instance 类 返回 boolean类型 通过子类实例化的对象同时是子类和父类的实例,无论是直接声明子类 ...
- Java中instanceof用法
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法:resu ...
- JAVA的instanceOf什么时候用啊
当你拿到一个对象的引用时(例如参数),你可能需要判断这个引用真正指向的类.所以你需要从该类继承树的最底层开始, 使用instanceof操作符判断,第一个结果为true的类即为引用真正指向的类. cl ...
随机推荐
- 两种高性能I/O设计模式(Reactor/Proactor)的比较
原文出处: Alex Libman 译文出处:潘孙友 欢迎分享原创到伯乐头条 综述 这篇文章探讨并比较两种用于TCP服务器的高性能设计模式. 除了介绍现有的解决方案,还提出了一种更具伸缩性,只 ...
- 重载和覆盖的区别?(overload vs override)
override与overload的区别? override 表示重写,overload 表示重载.override是子类和父类之间的关系,是垂直关系:overload是同一个类中方法之间的关系,是水 ...
- HDU 1558 Segment set (并查集+线段非规范相交)
题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. #include <cstdio> #inclu ...
- PYTHON发送邮件时,有的服务器不用密码认证的
#!/usr/bin/python # coding: UTF-8 import smtplib from email.mime.text import MIMEText receivers_list ...
- Java Applet与Java Application的特点
java application是应用程序,用于桌面开发,java applet是小应用程序,一般嵌入到网页里运行.applet一般用于B/S页面上作为插件式的开发,而application主要是桌面 ...
- web服务器【apache/nginx] 关闭目录的浏览权限
web服务器[apache/nginx] 关闭目录的浏览权限 我的配置(将Options 中的Indexes干掉): <VirtualHost *:80> ServerAdmin webm ...
- 一个简单的ObjC和JavaScript交互工具
https://github.com/changjianfeishui/XBWebBridge ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了.这里只 ...
- Android:Intel Atom x86模拟器的安装与使用
1.下载硬件加速执行管理器haxm-windows_r05.zip,找到系统对应版本,并安装 2.下载安卓x86系统映象sysimg_x86-19_r01.zip,不区分系统环境,解压得到x86文件夹 ...
- C#与USB HID间的通信
原文:C#与USB HID间的通信 C#与USBHID接口的通讯相对于与串口间的通讯较为复杂,其中需要多次调用到Windows的一些API.其原理编者尚未全部理清,以下提供简单的USBHID通讯流程. ...
- DB2操作流程
DB2如何创建表空间 如何创建数据库 如何创建缓冲池标签: db2数据库system脚本linuxwindows2012-06-13 19:16 8411人阅读 评论(0) 收藏 举报 版权声明:本文 ...