坑介紹,具體請先看代碼
public void test1(){
Integer a = null;
int b = 6;
if(b > a){
System.out.println("a>b");
}
}
上面的代碼編譯沒有什麼問題,但是運行就報錯空指針,具體原因就是自動拆箱引起的,
代碼分析
定義a和b,在if中做判斷的時候,因爲b是int類型,因爲會做值比較,a爲包裝類型,如果需要做值比較就需要拆箱,對a做拆箱
需要執行a.intValue()方法,但是a對null,因此會報空指針錯誤
額外知識點
1、如果“==”兩邊都是引用對象類型,則比較的是對象的內存地址是否一樣,如果其中一個是基本類型,則需要拆箱做值比較
除了"==",+、-、*、/ 運算都會做拆箱操作
代碼
public void test3(){
Integer a = 200;
Integer b = 200;
int c = 200;
System.out.println(a==b);//false
System.out.println(a==c);//true
}
2、當Interger 類型的變量賦值爲(-128,128]即裝箱操作(valueOf()),用"=="作比較,返回爲true,原因是jdk爲我們默認生成好了,這256個對應的Integer數組,而不需要重新new新的對象,jdk中對可以枚舉的都做了這樣的初始化,包括,Integer、Long、Short、Charactor;但是對Double、Float則不會這樣初始化操作
代碼
public void test4(){
Integer a = 100;
Integer b = 100;
int c = 100;
System.out.println(a==b);//true
System.out.println(a==c);//true
}
3、八種基本類的包裝對象的equals(Object o ),不僅要對應類型,還要對比具體的值 ;而對於其他對象類型比較的是內存的地址,但是String類的equals方式是重寫了的,是比較的對象的值而不是內存地址
代碼
public void test5(){
String[] str1 = {"1"};
String[] str2 = {"1"};
String s1 = "aa";
String s2 = "aa";
String s3 = new String("aa");
System.out.println(str1.equals(str2));//false
System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//true
}
其中爲什麼"s1==s2" 返回的是true呢,需要注意,
String s1 = "aa";
實際上是兩個步驟,首先創建了常量"aa",然後在創建String s1 ,然後在把s1 指向常量池中"aa" 的內存地址,在執行
String s2 = "aa";
的時候,現在常量池中查找是否有"aa"這個常量,如果有就直接把s2指向"aa"這個常量的內存地址,因此上述代碼中s1==s1返回爲true