Java和拳擊(自動裝箱)
當你已經開發了15年Java卻被同事問到如何debug一個null pointer exception(NPE 空指針異常)時, 可別太意外。通常情況下什么東西指向了“空”非常明顯,而唯一要做的就是找到它。
這有時候會更加困難一些,因為有些人創建了一系列的間接引用對象。有天我見識到了一些新鮮的東西,并且困惑了一陣子。從短暫的迷惑到最終發現問題根源是debug Java程序最有意思的體驗之一。
看看下面一段代碼并找出NPE出現在哪兒:
return value;
是的,一個簡單的return語句拋出了NPE。
這是為什么呢?這里并沒有顯式的間接引用。也沒有空值的引用。那個語句就像它看上去那么簡單。讓我來把這段代碼擴展一點好讓你更好的理解:
public int getValue(){ return value; }
又一次,我們看到一段非常簡單的代碼。通過這段代碼和我們文章標題的暗示,你可能已經明白是怎么回事,也可能更加困惑了。再重申一次,這里沒有被顯式間接引用的東西。我們甚至不是在處理一個引用,這個語句返回的是一個元始型變量。
通過這些線索,你想明白怎么回事兒了嗎?好了,給你看看完整的代碼和解釋吧:
package Example; public class Example { Integer value; public int getValue(){ return value; } }
注意value這個變量是Integer類型的,但是getValue的返回值為int型。
在Java 5 出現之前,上面這段代碼會出現編譯錯誤。但是Java 5 引進了自動裝箱(Autoboxing). 這個新特性伴隨了我一半的Java生涯并從未困擾過我。它一直是一個非常便利的特性。
自動裝箱使得基本類型和他們的第一類對象之間實現無縫轉換。你可以直接給value賦值而不用通過調用value.intValue來得到基本類型。但實際上intValue還是會被調用。
這就是為什么會拋出NPE了。問題中的那行代碼變成如下這樣:
return value.intValue();
在這行里,哪里拋出了NPE就很明顯了。
哦對了, 提醒一下,拳擊運動叫做甜蜜的科學(The Sweet Science)。我覺得自己被自動裝箱狠狠打了一拳,所以想到了這個題目。
(譯注:英文中The Sweet Science代指拳擊Boxing,與Java的裝箱技術名字相同)
原文鏈接: javacodegeeks 翻譯: ImportNew.com - fanchao
譯文鏈接: http://www.importnew.com/13650.html