【java】——自動拆箱和裝箱的坑

坑介紹,具體請先看代碼

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章