IT七剑客 IT七剑客
首页
wresource
郭霖
孤寒者
IT邦德
沉默王二
老麦
stackoverflow
GitHub (opens new window)
首页
wresource
郭霖
孤寒者
IT邦德
沉默王二
老麦
stackoverflow
GitHub (opens new window)
  • Java基础语法

  • 程序人生

  • 实用工具

  • Java重要知识点

    • Java中常用的48个关键字和2个保留字
    • 深入理解Java中的注解
    • 深入剖析Java中的拆箱和装箱
    • 先有Class还是先有Object?
    • 详解Java中Comparable和Comparator的区别
    • 彻底讲明白的Java浅拷贝与深拷贝
    • Java枚举(enum)
    • 一次性搞清楚equals和hashCode
    • 大白话说Java反射:入门、使用、原理
    • 深入理解Java泛型
    • 深入理解Java中的hashCode方法
    • 深入理解Java中的不可变对象
    • instanceof关键字是如何实现的?
      • Java中int、Integer、new Integer之间的区别
      • Java命名规范,告别编码 5 分钟,命名 2 小时
      • 彻底弄懂Java中的Unicode和UTF-8编码
      • jdk9为何要将String的底层实现由char[]改成了byte[]?
      • 为什么JDK源码中,无限循环大多使用for(;;)而不是while(true)?
      • Java 方法重写 Override 和方法重载 Overload 的区别,一下子就明白了
      • Java重写(Overriding)时应当遵守的11条规则
      • Java到底是值传递还是引用传递?
      • Java不能实现真正泛型的原因是什么?
      • Java中可变参数的使用
    • Java工具

    • 数组与字符串

    • 沉默王二 Java
    • Java重要知识点
    沉默王二
    2023-01-22
    目录

    instanceof关键字是如何实现的?

    # instanceof关键字是如何实现的?

    小二那天去面试,碰到了这个问题:“instanceof 关键字是如何实现的?”面试官希望他能从底层来分析一下,结果小二没答上来,就来问我。

    我唯唯诺诺,强装镇定,只好把 R 大的一篇回答甩给了他,并且叮嘱他:“认认真真看,玩完后要是还不明白,再来问我。。。”

    作者:RednaxelaFX,整理:沉默王二,链接:https://www.zhihu.com/question/21574535/answer/18998914


    # 场景一:月薪 3000 元一下的码农职位

    用 Java 伪代码来表现instanceof关键字在Java语言规范所描述的运行时语义,是这样的:

    // obj instanceof T
    boolean result;
    if (obj == null) {
      result = false;
    } else {
      try {
          T temp = (T) obj; // checkcast
          result = true;
      } catch (ClassCastException e) {
          result = false;
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    用中文说就是:如果有表达式 obj instanceof T,那么如果 obj 不为 null 并且 (T) obj 不抛 ClassCastException 异常则该表达式值为 true ,否则值为 false 。

    如果面试官说“这不是废话嘛”,进入场景二。

    # 场景二:月薪6000-8000的Java研发职位

    JVM有一条名为 instanceof 的指令,而Java源码编译到Class文件时会把Java语言中的 instanceof 运算符映射到JVM的 instanceof 指令上。

    javac是这样做的:

    • instanceof 是javac能识别的一个关键字,对应到Token.INSTANCEOF的token类型。做词法分析的时候扫描到"instanceof"关键字就映射到了一个Token.INSTANCEOF token。
    • 该编译器的抽象语法树节点有一个JCTree.JCInstanceOf类用于表示instanceof运算。做语法分析的时候解析到instanceof运算符 (opens new window)就会生成这个JCTree.JCInstanceof类型的节点。
    • 中途还得根据Java语言规范对instanceof运算符的编译时检查的规定把有问题的情况找出来。
    • 到最后生成字节码的时候为JCTree.JCInstanceof节点生成instanceof字节码指令。

    回答到这层面就已经能解决好些实际问题了,如果面试官还说,“这不还是废话嘛”,进入场景三。

    # 场景三:月薪10000的Java高级研发职位

    先简单介绍一下instanceof的字节码:

    • 操作:确定对象是否为给定的类型
    • 指令格式:instanceof|indexbyte1|indexbyte2
    • 指令执行前后的栈顶状态:
      • ……,objectref=>
      • ……,result

    再简单描述下:indexbyte1和indexbyte2用于构造对当前类的常量池的索引,objectref为reference类型,可以是某个类,数组的实例或者是接口。

    基本的实现过程:对indexbyte1和indexbyte2构造的常量池索引进行解析,然后根据java规范判断解析的类是不是objectref的一个实例,最后在栈顶写入结果。

    基本上就是根据规范来 YY 下实现,就能八九不离十蒙混过关了。

    如果面试官还不满意,进入场景四。

    # 场景四:月薪10000以上的Java资深研发职位

    这个岗位注重性能调优什么的,R 大说可以上论文了:

    https://dl.acm.org/doi/10.1145/583810.583821

    论文我也看不懂,所以这里就不 BB 了。(逃

    篇论文描述了HotSpot VM做子类型判断的算法,这里简单补充一下JDK6至今的HotSpot VM实际采用的算法:

    S.is_subtype_of(T) := {
      int off = T.offset;
      if (S == T) return true;
      if (T == S[off]) return true;
      if (off != &cache) return false;
      if ( S.scan_secondary_subtype_array(T) ) {
        S.cache = T;
        return true;
      }
      return false;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    HotSpot VM的两个编译器,Client Compiler (C1) 与 Server Compiler (C2) 各自对子类型判断的实现有更进一步的优化。实际上在JVM里,instanceof的功能就实现了4份,VM runtime、解释器、C1、C2各一份。

    VM runtime的:

    http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/tip/src/share/vm/oops/oop.inline.hpp

    分享的最后,二哥简单来说一下。

    这个问题涉及语法细节,涉及jvm实现,涉及编译器,还涉及一点点数据结构设计,比较考验一个 Java 程序员的内功,如果要回答到论文的程度,那真的是,面试官也得提前备好知识点,不然应聘者的回答啥也听不懂就挺尴尬的。

    反正 R 大回答里的很多细节我都是第一次听,逃了逃了。。。。。。


    最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关 等等等等……详情戳:可以说是2022年全网最全的学习和找工作的PDF资源了 (opens new window)

    关注二哥的原创公众号 沉默王二,回复111 即可免费领取。

    编辑 (opens new window)
    #沉默王二#Java
    上次更新: 2023/01/22, 15:00:47
    深入理解Java中的不可变对象
    Java中int、Integer、new Integer之间的区别

    ← 深入理解Java中的不可变对象 Java中int、Integer、new Integer之间的区别→

    最近更新
    01
    Coding 102 Writing code other people can read
    02-26
    02
    Kotlin Flow响应式编程,StateFlow和SharedFlow
    02-05
    03
    Kotlin Flow响应式编程,操作符函数进阶
    02-05
    更多文章>
    Theme by Vdoing | Copyright © 2022-2023 IT七剑客 | MIT License
  • 闽ICP备2021006579号-4
  • 闽公网安备 35012102500470号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式