一個(gè)三目運(yùn)算符引發(fā)的“血案”

問(wèn)題描述

今天有個(gè)同事發(fā)過(guò)來(lái)一個(gè)消息,說(shuō)他的系統(tǒng)今天老是報(bào)錯(cuò)誤,代碼看了好幾次都沒(méi)發(fā)現(xiàn)問(wèn)題,百思不得其解,讓我?guī)兔囱?。我拿到代碼后,乍一看也沒(méi)看出個(gè)所以然,但是在執(zhí)行單元測(cè)試之后,問(wèn)題很快就暴露出來(lái)了,坑啊~~~~ 大致代碼如下:

        class Operator{
            Long cityIdCharge;
            .....
        }

        ......
        
        Operator operator = new Operator();
        Long currentCityId = operator == null ? 0L : operator.getCityInCharge();
        System.out.println(currentCityId);

在執(zhí)行如上代碼時(shí),將會(huì)拋出NPE異常,而且錯(cuò)誤位于代碼第二行。那為什么執(zhí)行第二行代碼會(huì)出現(xiàn)NPE錯(cuò)誤呢,下面我們來(lái)分析一下。

原因分析

根據(jù)異常堆棧,可以看到,異常定位于第二行代碼。第二行代碼是一個(gè)三元表達(dá)式,我們知道三目運(yùn)算符只要后面兩個(gè)是不同的類型,涉及到類型轉(zhuǎn)換,那么編譯器就會(huì)向下(基本類型)進(jìn)行轉(zhuǎn)型,再進(jìn)行計(jì)算。換言之,如果在計(jì)算表達(dá)式中,有Integer和int,那么Integer類型會(huì)先轉(zhuǎn)化為int再進(jìn)行計(jì)算。
在開(kāi)始分析代碼之前,需要回顧一下java的基本數(shù)據(jù)類型。long是8種基本數(shù)據(jù)類型之一,Long是long的包裝類,繼承于Number類。
在示例代碼中,operator.getCityInCharge()返回的是Long類型,值為null。三元表達(dá)式的第二個(gè)值是0L,我們知道,Long的默認(rèn)值是null.long的默認(rèn)值是0L,因此,對(duì)于上述示例代碼中的第二行代碼,Long和long不是同一個(gè)類型,編譯器會(huì)默認(rèn)向下轉(zhuǎn)型,Long轉(zhuǎn)為long,但是此時(shí)Long類型對(duì)應(yīng)的值為null,因此拋出NPE。

Long與long之間的相互轉(zhuǎn)化

  1. 拆箱操作
    可以使用longValue()方法將Long變?yōu)閘ong
 Long a = 1L;
 long b = a.longValue();

也可以直接進(jìn)行拆箱操作

long c = a;

  1. 裝箱操作
    可以使用new方法將long變成Long

long a = 1L;
Long b = new Long(a);
也可以直接進(jìn)行裝箱操作
Long c = a;

因此上述的示例代碼可以修改為

Long currentCityId = operator == null ? new Long(0) : operator.getCityInCharge();

或者使用Optional結(jié)構(gòu)對(duì)operator.getCityInCharge()進(jìn)行封裝后再進(jìn)行計(jì)算

Optional.ofNullable(operator.getCityInCharge()).orElse(0L)

寫(xiě)在最后

  1. 在使用對(duì)象時(shí),需要先驗(yàn)空,再進(jìn)行操作處理,也可以使用guava中的Optional對(duì)對(duì)象進(jìn)行封裝
  2. 使用三元運(yùn)算符時(shí)最后使用相同類型的對(duì)象
  3. 一般來(lái)說(shuō),屬性的值建議使用封裝類型,臨時(shí)變量建議使用基本類型
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容