在进入正题前先得提一句:既然楼主提问的背景是“被面试问到”,那很重要的一点是揣摩面试官提问的意图。按照楼主的简单描述,面试官问的是“Java的instanceof关键字是如何实现的”,那要选择怎样的答案就得看面试官有怎样的背景。比较安全的应对方法是请求面试官澄清/细化他的问题——他想要的“底层”底到什么程度。
情形1
你在面月薪3000以下的Java码农职位。如果面试官也只是做做Java层开发的,他可能只是想让你回答Java语言层面的 instanceof 运算符的语义。Java语言的“意思”就已经是“底层”。这样的话只要参考Java语言规范对 instanceof 运算符的定义就好:
15.20.2 Type Comparison Operator instanceof,Java语言规范Java SE 7版,当然这实际上回答的不是“如何实现的”,而是“如何设计的”。但面试嘛⋯如果用Java的伪代码来表现Java语言规范所描述的运行时语义,会是这样:
// obj instanceof Tbooleanresult; if (obj==null) { result=false; } else { try { Ttemp= (T) obj; // checkcastresult=true; } catch (ClassCastExceptione) { result=false; } }
用中文说就是:如果有表达式 obj instanceof T ,那么如果 obj 不为 null 并且 (T) obj 不抛 ClassCastException 异常则该表达式值为 true ,否则值为 false 。
注意这里完全没提到JVM啊Class对象啊啥的。另外要注意 instanceof 运算符除了运行时语义外还有部分编译时限制,详细参考规范。
如果这样回答被面试官说“这不是废话嘛”,请见情形2。
情形2
你在面月薪6000-8000的Java研发职位。面试官也知道JVM这么个大体概念,但知道的也不多。JVM这个概念本身就是“底层”。JVM有一条名为 instanceof 的指令,而Java源码编译到Class文件时会把Java语言中的 instanceof 运算符映射到JVM的 instanceof 指令上。
你可以知道Java的源码编译器之一javac是这样做的:
- instanceof 是javac能识别的一个关键字,对应到Token.INSTANCEOF的token类型。做词法分析的时候扫描到"instanceof"关键字就映射到了一个Token.INSTANCEOF token。jdk7u/jdk7u/langtools: 5c9759e0d341 src/share/classes/com/sun/tools/javac/parser/Token.java
- 该编译器的抽象语法树节点有一个JCTree.JCInstanceOf类用于表示instanceof运算。做语法分析的时候解析到instanceof运算符就会生成这个JCTree.JCInstanceof类型的节点。jdk7u/jdk7u/langtools: 5c9759e0d341 src/share/classes/com/sun/tools/javac/parser/JavacParser.java term2Rest()
- 中途还得根据Java语言规范对instanceof运算符的编译时检查的规定把有问题的情况找出来。
- 到最后生成字节码的时候为JCTree.JCInstanceof节点生成instanceof字节码指令。jdk7u/jdk7u/langtools: 5c9759e0d341 src/share/classes/com/sun/tools/javac/jvm/Gen.java visitTypeTest()
(Java语言君说:“instanceof 这问题直接交给JVM君啦”)(面试官:你还给我废话⋯给我进情形3!)
其实能回答到这层面就已经能解决好些实际问题了,例如说需要手工通过字节码增强来实现一些功能的话,知道JVM有这么条 instanceof 指令或许正好就能让你顺利的使用 ASM 之类的库完成工作。