作為一名java程式設計師,求職面試時,不知你有沒有遇到,面試官提問的問題很簡單,可自己卻答錯了。
有次,我到一家網際網路公司應聘,公司前臺妹子叫我先做一下筆試題,其中有一道題目是這樣的:
publicclassIntegerTest {publicstaticvoidmain(String[] args) {Integer i = 10, j = 10; Integer m = 600, n = 600; System.out.println(i == j); System.out.println(m == n); System.out.println(m.equals(n)); }}
請問程序結果輸出什麼,我不假思索地選擇了
truetruetrue
心裡還想著,怎麼出這麼簡單的題目,後來面試官看了筆試題後,說,你都工作兩年了,我看你做的項目也不少,怎麼這樣的題目都做錯了。說得我特別不好意思。
正確答案應該是:
truefalsetrue
其實這道題目無非就是考察兩點,java裝箱和拆箱的問題。
一.什麼是裝箱?什麼是拆箱?
裝箱 就是自動將基本數據類型轉換為包裝器類型;拆箱 就是自動將包裝器類型轉換為基本數據類型在電商平臺中,商家寄快遞,打包,這個操作我們叫做裝箱,消費者買東西收到快遞後拆包,叫拆箱,那麼java程序中的裝箱又是怎樣的呢,下面我們來看看具體例子。
在程序中,如果我們需要生成一個數值的對象,可以這樣使用
Integer a = 100; //裝箱
這個過程就會根據數值創建對應的 Integer 對象這就是裝箱
而拆箱呢,則可以這樣
int b = a; //拆箱
這個時候就是拆箱操作。
或許上面的解析過於籠統,下面我們再寫個例子來反編譯一下,進一步驗證下,看看整個過程調用了哪些方法。
publicclassIntegerTest {publicstaticvoidmain(String[] args){Integer i = 100;int j = i; }}
反編譯之後的結果如下:
從反編譯的結果我們可以得知,在裝箱的時候,調用了 Integer 的 valueOf(int i) 方法;而在拆箱的時候,則調用了 Integer 的 intValue() 方法。
關於 Integer.valueOf方法,我們來看下它的源碼
publicstatic Integer valueOf(int i){if (i >= Integer.IntegerCache.low && i <= Integer.IntegerCache.high)return Integer.IntegerCache.cache[i + (-Integer.IntegerCache.low)];returnnew Integer(i);}
通過源碼可以看到,在 Interger 的 valueOf 方法中,如果數值在 [-127, 128] 範圍的時候,就會去 IntegerCache.cache 這個數組尋找有沒有存在的 Integer 對象的引用,如果有,則直接返回對象的引用,如果沒有(超過了範圍),就新建一個 Integer 對象。
現在我們再回過頭來再看看文中開頭的題目
Integer m = 600,n =600;
600不在這個 [-127, 128] 範圍,所以我們用 == 程序就返回false 而用equals 這返回true 。
equals方法是這樣定義的,先拆箱為int再比較
publicbooleanequals(Object obj){if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}returnfalse; }
總結
Integer裝箱操作:例如 Integer i= 3;這種格式的代碼,將編譯成
Integer i=Integer.valueOf(3);
這就是裝箱操作。Integer拆箱操作:在編譯期將Integer轉換成int類型,會調用int j = i.intValue()方法,拆箱操作在例子中表現為,int類型與Integer類型進行==比較,此時Integer會進行拆箱操作。
以上只是關於java裝箱和拆箱的簡單分析,由於筆者水平有限,文中紕漏之處在所難免,權當拋磚引玉,不妥之處,請大家批評指正。