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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章