zoukankan      html  css  js  c++  java
  • 包装类==比较关于null 的问题

    今天线上遇到一个空指针问题,觉得是一个小知识点,想想还是记录下来(拆箱问题)

      public static void main(String[] args) {
            int i=0;
            Integer s=null;
            if(s==i){
                System.out.println(s+"1");
            }else
            {
                System.out.println(s+"2");
            }
    
        }

    写一个小demo,正常我们一个判断是上面这个代码块

    上述integer和int 进行==比较,这样写的话会出现空指针

    下面我们简化下来看下反编译之后的汇编指令.

      public static void main(String[] args) {
            int i=0;
            Integer s=null;
            boolean b=s==i;
        }

    反编译结果如下:

     可以看到一个指令:invokevirtual -->调用实例方法,基于类进行分派,意思就是去调用integer的intValue方法

    这样我们就可以知道为什么会出现空指针了(拆箱)

    上面我们可以知道不同类型变量之前的比较会进行装箱拆箱,那相同类型是怎么比较的呢?

    我们把上述代码进行小小的改变(i换成了integer)

      public static void main(String[] args) {
            Integer i=0;
            Integer s=null;
            boolean b=s==i;
        }

    然后我们再看下反编译的代码

     首先iconst_0 -->,int取值0~5时JVM采用iconst_0、iconst_1、iconst_2、iconst_3、iconst_4、iconst_5指令将常量压入栈中,取值-1时采用iconst_m1指令将常量压入栈中

    第二步调用integer的valueOf方法

    这段代码我们应该很熟悉,integer的一个缓存方案,(-128~128),这里也涉及到一个integer的比较问题(最好使用equals比较,如果使用==的话要考虑128之后的问题)

     第三步astore_1-->要执行astore_1指令,JVM从操作数栈顶部弹出一个引用类型或者returnAddress类型值,然后将该值存入由索引1指定的局部变量中,即将引用类型或者returnAddress类型值存入局部变量1。

    第四步aload_1-->从局部变量表的相应位置装载一个对象引用到操作数栈的栈顶

    第五步:if_acmpne-->比较栈顶两引用类型数值,当结果不相等时跳转

    经过两步aload 将值装载到操作数栈的栈顶,然后用if_acmpne进行比较

  • 相关阅读:
    寻找两个有序数组的中位数
    JAVA设计模式(组合模式)
    excel 操作
    研究生英语-春
    cvs
    Spring课程安排
    Spring的事务管理
    在WEB项目中集成Spring
    计算机网络参考模型
    揭开5G神秘面纱
  • 原文地址:https://www.cnblogs.com/xwx20160804/p/13891703.html
Copyright © 2011-2022 走看看