溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中使用三元表達式會遇到什么問題

發(fā)布時間:2021-12-29 17:21:11 來源:億速云 閱讀:320 作者:小新 欄目:大數(shù)據(jù)

小編給大家分享一下java中使用三元表達式會遇到什么問題,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!


一、問題重現(xiàn)

public class Test {
    public static void main(String[] args) {
        Integer a = null;
        boolean flag = false;
        Integer b = flag ? 1*2 : a;
        System.out.println("程序結束");
    }
}
 

代碼很簡單,a是包裝類型Integer,初始值是null,b通過三元表達式進行賦值。運行一下這個代碼就會出現(xiàn)空指針異常:

java中使用三元表達式會遇到什么問題

為什么會出現(xiàn)這個現(xiàn)象呢?下面我們來分析一下:

 

二、問題分析

剛剛這個空指針現(xiàn)象很容易我們就想到類型轉化上,三元表達式的類型轉換同樣要遵守一定的規(guī)則才可以。

1、三元操作符類型的轉換規(guī)則:

(1)若兩個操作數(shù)不可轉換,則不做轉換,返回值為Object類型

比如Object b =  flag ?  A : B,此時A和B是兩個不同的對象,不可轉換,那就把最終結果賦值給Object

(2)若兩個操作數(shù)是明確類型的表達式(比如變量),則按照正常的二進制數(shù)字來轉換,int類型轉換為long類型,long類型轉換為float類型等。

這個就比較容易理解了,比如float b = flag ? 1:1.0f。1為int類型向上轉即可。

(3)若兩個操作數(shù)中有一個是數(shù)字S,另外一個是表達式,且其類型標示為T,那么,若數(shù)字S在T的范圍內,則轉換為T類型;若S超出了T類型的范圍,則T轉換為S類型。

這種情況就是剛剛我們所演示的例子,Integer b = flag ? 1 *2: a,結果是b=a,但是a是null,要強制轉換成Integer(1 * 2的類型),于是就出現(xiàn)了空指針。

(4)若兩個操作數(shù)都是直接量數(shù)字,則返回值類型為范圍較大者。

這種情況和第二種類似。

現(xiàn)在答案基本上出來了,出現(xiàn)空指針的原因是,a=null,要強制轉換Integer,于是出現(xiàn)了空指針,因為虛擬機看到一個null就找不到要轉化的對象了。

2、反編譯分析

現(xiàn)在我們找到Test的字節(jié)碼文件,輸入javap -c命令,反編譯一下:

java中使用三元表達式會遇到什么問題

答案現(xiàn)在應該清楚了,

3、為什么要拆箱(重點)

為什么要對a進行拆箱,直接把a=null賦值給b不就完事了嘛。這一點就需要我們注意一下那個前提條件,也就是說一個是數(shù)字,一個是表達式,剛剛的那個例子也驗證了這個觀點,現(xiàn)在我不是表達式,再來驗證一下:

java中使用三元表達式會遇到什么問題

現(xiàn)在我們可以看到不是表達式,依然會出現(xiàn)這個錯誤。別著急,還有讓你更暈的,我們再來改變一下代碼:

java中使用三元表達式會遇到什么問題

這尼瑪惡心,我測試了很多不同的案例,基本上就分為這兩種情況。原因如下:

條件表達式?表達式 1 :表達式 2,假設結果是表達式2

(1)表達式1和2都為null,表達式2看到1是null,則不會進行拆箱。

(2)表達式1為數(shù)字或者是表達式,表達式2根據(jù)1的類型進行拆箱。

也就是說表達式2主要依據(jù)表達式1判斷是否進行拆箱操作。

 

三、問題解決

解決方案很簡單,那就是只要遇見null在三元表達式里,就盡量轉化為if結構。

看完了這篇文章,相信你對“java中使用三元表達式會遇到什么問題”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI