null == 0 和 0 == null 为什么会报NPE空指针异常

下面测试代码运行后,会出现NullPointerException,一般人都会感觉奇怪,为什么会报NullPointerException。

    @Test
    public void test(){
        Integer code = null;
        // 这里会报NPE异常,原因;
        // Integer 拆箱的问题, 0 是int类型,比较时code会自动拆箱,拆箱调用的是Integer里的intValue()方法,而此时code是null,自然就会报NPE异常
        if (code  == 0){
            System.out.println("会报NEP异常");
        }
    }

原因分析:

通过对.class文件(javap -c xx.class)反汇编可以看到,Code序号4,调用了Integer.intValue()方法,为什么呢,这得从int和Integer的关系说起,Integer跟int比较时,会存在一个拆箱的过程,也就是把Integer转换成int,实际就是调用了Integer.intValue()方法,当执行null.intValue()方法自然就会出现NPE异常了。

// javap -c xx.class 后看到的反汇编代码
public void test();
    Code:
       0: aconst_null
       1: astore_1
       2: iconst_0
       3: aload_1
       4: invokevirtual #7                  // Method java/lang/Integer.intValue:()I
       7: if_icmpne     18
      10: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
      13: ldc           #9                  // String ==============
      15: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      18: return

PS:
Integer a = 1;这样声明一个Integer类型的a变量,就会把int类型的1自动装箱成Integer对象,用javap -c 命令会发现,底层实际就是调用了Integer.valueOf(int i)方法实现装箱。

// 实现装箱的方法,从这里也能看出Integer的缓存池是[-128 , 127]之间。
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章