Java 三目運算符表達式的一些問題
最近在處理一個需求,需求描述如下:對數據庫中查詢出來的數據的某一個字段做一個簡單處理。處理方式是:如果該字段的值(取值範圍0~4,有可能為null)等於0,那麽默認處理成1。
測試代碼如下:
1 public class TestNull { 2 3 private Integer starLevel; 4 5 public Integer getStarLevel() { 6 return starLevel; 7 } 8 9 public void setStarLevel(Integer starLevel) { 10 this.starLevel = starLevel; 11 } 12 13 public static void main(String[] args) { 14 TestNull test = new TestNull(); 15 16 Integer localStartLevel = 17 test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : test.getStarLevel(); 18 19 System.out.println(localStartLevel);20 } 21 22 }
因為不想寫if-else,所以直接使用了三目運算符,原因嘛肯定是方便、簡潔呀。一切都大功告成了,感覺自己棒棒噠!!!然後開始自測(發現代碼沒什麽問題的童鞋不妨copy一下上面的代碼執行一下),報錯了!!!空!指!針!
老實說,當時我擼這段代碼很自信,我調試這段代碼也看了三遍才找到原因。如果你也沒找到原因,你可以把那個1換成Integer.valueOf(1)或者將分號後面的test.getStarLevel()
直接換成null(當然這樣是不符合需求的)再試試。
問題原因:可能你也發現問題所在了,就是因為那個“方便、簡潔”的三目運算符表達式
分析原因:
1、test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : test.getStarLevel()
結論:錯誤!因為有個分支是返回基本類型數值1,另一個分支返回的直接是對象的調用值(該值的類型在運行時動態確定的),所以,三目運算符幫我們統一處理成了基本類型裝箱操作。所以null裝箱肯定空指針。
2、test.getStarLevel() != null && test.getStarLevel() == 0 ? Integer.valueOf(1) : test.getStarLevel();
結論:正確!因為基本類型1已經被初始化為Integer對象了,然後這個賦值表達式都是直接賦值引用了,所以不會存在問題。
3、test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : null
結論:正確!該段跟第一段代碼的唯一區別就是test.getStarLevel()換成了null,這就消滅了運行時動態確定該分支的返回值類型的不確定性,所以能夠正確執行。
三目運算符固然是好用,但是使用時還是需要註意返回值類型的統一性呀!且用且珍惜!
該博客僅代表個人觀點,如有不足之處,請不吝惜指教!!!
Thanks!!!
Java 三目運算符表達式的一些問題