• 包装类==比较关于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进行比较

  • 相关阅读:
    取消a标签的页面跳转
    js 获取元素内部文本
    彻底取消Myeclipse对js文件的校验
    控制流程之if判断
    格式化的三种输出方式和基本运算符以及他们的优先级
    解压缩和python如何与用户交互
    数据类型基础和各种数据类型
    花式赋值和注释
    变量 及其命名和使用规范
    进入的python世界。了解执行python的交互方式和常用开发工具
  • 原文地址:https://www.cnblogs.com/xwx20160804/p/13891703.html
Copyright © 2020-2023  润新知