下面測試代碼運行後,會出現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);
}