1. 程式人生 > >關於自動裝箱的一道題

關於自動裝箱的一道題

昨天在社團面試的時候看到的一道題目,想到之前也有做過筆記,就貼出來一下

 public class Wrapper {
        public static void main(String[] args) {
            Integer a = 100;
            Integer b = 100;
            Integer c = 1000;
            Integer d = 1000;
            System.out.println(a==b);
            System.out.println(c==d);
        }
    }

如果你什麼都不知道,那你可能會認為答案是 true true 如果你知道比較要用equals方法的話,那你的答案可能是 false false 但是實際上答案是 true false 為什麼答案會是這樣呢,這就涉及到java的自動裝箱機制了 一般來說,a==b會比較兩個物件的地址是否指向同一個儲存區域 而不是比較它們的值,所以下面這個例子的結果是false這是理所當然的

 Integer c = 1000;
 Integer d = 1000;
 System.out.println(c==d);

但是,自動裝箱規範要求boolean、byte、char<=127,short、int屬於-128~127之間的數都被包裝到固定的物件中,即:

關於該規範的描述摘自《java核心技術卷一》

short a = 20;
byte b = 20;
Integer c = 20;
System.out.println(a == b);
System.out.println(b == c);

結果是兩個true,因為它們都包裝在同一個物件中 當然,就算是在-128~127這個範圍內,資料不同的話是不會包裝在一個物件中的,如:

Integer a = 20;
Integer b = 100;
System.out.println(a == b); // 結果當然是false

當然,有人可能會好奇自動裝箱是什麼東西,這裡舉一個小例子:

ArrayList<Integer> list=new ArrayList<>();
int a = 3;
list.add(a);

我們都知道,ArrayList泛型陣列的定義要用包裝類,也就是Integer,那麼,我們要如何把一個int型別的資料新增進一個Integer的陣列呢? 事實上,在執行新增操作的時候java會自動幫你完成 list.add(Integer.valueOf(a)); 的操作,也就是將int轉換成Integer,而這,就是自動裝箱

實際上,在最初的例子的那道題中,Integer a = 100; 我認為被java改成了這樣的操作:

Integer a = Integer.valueOf(100);

所以這種直接賦值實際上都被自動裝箱了,如果你用以下的方法賦值:

Integer a = new Integer(100);
Integer b = new Integer(100);
System.out.println(a==b);

則不會被自動裝箱,所以結果是false