精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

這么簡單的三目運算符竟然也有這么多坑?

開發 前端
最近,阿粉在一個業務改造中,使用三目運算符重構了業務代碼,沒想到測試的時候竟然發生 NPE 的問題。

[[328294]]

最近,阿粉在一個業務改造中,使用三目運算符重構了業務代碼,沒想到測試的時候竟然發生 NPE 的問題。

[[328295]]

重構代碼非常簡單,代碼如下:

  1. // 方法返回參數類型為 Integer 
  2. //  private Integer code; 
  3. SimpleObj simpleObj = new SimpleObj(); 
  4. // 其他業務邏輯 
  5. if (simpleObj == null) { 
  6.     return -1; 
  7. else { 
  8.     return simpleObj.getCode(); 

這段 if 判斷,阿粉看到的時候,感覺很是繁瑣,于是使用三目運算符重構了一把,代碼如下:

  1. // 方法返回參數類型為 Integer 
  2. SimpleObj simpleObj = new SimpleObj(); 
  3. // 其他業務邏輯 
  4. return simpleObj == null ? -1 : simpleObj.getCode(); 

測試的時候,第四行代碼拋出了空指針,這里代碼很簡單,顯然只有 simpleObj#getCode才有可能發生 NPE 問題。

但是我明明為 simpleObj做過判空判斷,simpleObj 對象肯定不是 null,那么只有 simpleObj#getCode 返回為 null。但是我的代碼并沒有對這個方法返回值做任何操作,為何會觸發 NPE?

難道是又是自動拆箱導致的 NPE 問題?

在解答這個問題之前,我們首先復習一下三目運算符。

三目運算符

三目運算符,官方英文名稱:Conditional Operator ? :,中文直譯條件表達式,本文不糾結名稱,統一使用三目運算符。

三目運算符的基本用法非常簡單,它由三個操作數的運算符構成,形式為:

  1. <表達式 1><表達式 2>:<表達式 3> 

三目運算符的計算從左往右計算,首先需要計算計算表達式 1 ,其結果類型必須為 Boolean 或 boolean,否則發生編譯錯誤。

當表達式 1 的結果為 true,將會執行表達式 2,否則將會執行表達式 3。

表達式 2 與表達式 3 最后的類型必須得有返回結果,即不能為是 void,若為 void ,編譯時將會報錯。

最后需要注意的是,表達式 2 與表達式 3 不會被同時執行,兩者只有一個會被執行。

踩坑案例

了解完三目運算符的基本原理,我們簡化一下開頭例子,復現一下三目運算符使用過程的一些坑。假設我們的例子簡化成如下:

  1. boolean flag = true; //設置成true,保證表達式 2 被執行 
  2. int simpleInt = 66; 
  3. Integer nullInteger = null

案例 1

第一個案例我們根據如下計算 result 的值。

  1. int result = flag ? nullInteger : simpleInt; 

這個案例為開頭的例子的簡化版本,運算上述代碼,將會發生 NPE 的。

為什么會發發生 NPE 呢?

這里可以給大家一個小技巧,當我們從代碼上沒辦法找到答案時,我們可以試試查看一下編譯之后字節碼,或許是 Java 編譯之后增加某些東西,從而導致問題。

使用 javap -s -c class 查看 class 文件字節碼,如下:

可以看到字節碼中加入一個拆箱操作,而這個拆箱只有可能發生在 nullInteger。

那么為什么 Java 編譯器在編譯時會對表達式進行拆箱?難道所有數字類型的包裝類型都會進行拆箱嗎?

三目運算符表達式發生自動拆箱,其實官方在 「The Java Language Specification(簡稱:JLS)」15.25 節[1]中做出一些規定,部分內容如下:

  • JDK7 規范
  • If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

用大白話講,如果表達式 2 與表達式 3 類型相同,那么這個不用任何轉換,三目運算符表達式結果當然與表達式 2,3 類型一致。

當表達 2 或表達式 3 其中任一一個是基本數據類型,比如 int,而另一個表達式類型為包裝類型,比如 Integer,那么三目運算符表達式結果類型將會為基本數據類型,即 int。

  • ps:有沒有疑問?為什么不規定最后結果類型都為包裝類那?

這是 Java 語言層面一種規范,但是這個規范如果強制讓程序員執行,想必平常使用三目運算符將會比較麻煩。所以面對這種情況, Java 在編譯器在編譯過程加入自動拆箱進制。

所以上述代碼可以等同于下述代碼:

  1. int result = flag ? nullInteger.intValue() : simpleInt; 

如果我們一開始的代碼如上所示,那么這里錯誤點其實就很明顯了。

案例 2

接下來我們在第一個案例基礎上修改一下:

  1. boolean flag = true; //設置成true,保證表達式 2 被執行 
  2. int simpleInt = 66; 
  3. Integer nullInteger = null
  4. Integer objInteger = Integer.valueOf(88); 
  5.  
  6. int result = flag ? nullInteger : objInteger; 

運行上述代碼,依然會發生 NPE 的問題。當然這次問題發生點與上一個案例不一樣,但是錯誤原因卻是一樣,還是因為自動拆箱機制導致。

這一次表達式 2 與表達式 3 都為包裝類 Integer,所以三目運算符的最后結果類型也會是 Integer。

但是由于 result是 int 基本數據類型,好家伙,數據類型不一致,編譯器將會對三目運算符的結果進行自動拆箱。由于結果為 null,自動拆箱將報錯了。

上述代碼等同為:

  1. int result = (flag ? nullInteger : objInteger).intValue(); 

案例 3

我們再稍微改造一下案例 1 的例子,如下所示:

  1. boolean flag = true; //設置成true,保證表達式 2 被執行 
  2. int simpleInt = 66; 
  3. Integer nullInteger = null
  4. Integer result = flag ? nullInteger : simpleInt; 

案例 3 與案例 1 右邊部分完全相同,只不過左邊部分的類型不一樣,一個為基本數據類型 int,一個為 Integer。

按照案例 1 的分析,這個也會發生 NPE 問題,原因與案例 1 一樣。

這個之所以拿出來,其實想說下,上述三目運算符的結果為 int 類型,而左邊類型為 Integer,所以這里將會發生自動裝箱操作,將 int類型轉化為 Integer。

上述代碼等同為:

  1. Integer result = Integer.valueOf(flag ? nullInteger.intValue() : simpleInt); 

案例 4

最后一個案例,與上面案例都不一樣,代碼如下:

  1. boolean flag = true; //設置成true,保證表達式 2 被執行 
  2. Integer nullInteger = null
  3. Long objLong = Long.valueOf(88l); 
  4.  
  5. Object result = flag ? nullInteger : objLong; 

運行上述代碼,依然將會發生 NPE 的問題。

這個案例表達式 2 與表達式 3 類型不一樣,一個為 Integer,一個為 Long,但是這兩個類型都是 Number的子類。

面對上述情況,JLS 規定:

  • Otherwise, binary numeric promotion (§5.6.2[2]) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.
  • Note that binary numeric promotion performs value set conversion (§5.1.13[3]) and may perform unboxing conversion (§5.1.8[4]).

大白話講,當表達式 2 與表達式 3 類型不一致,但是都為數字類型時,低范圍類型將會自動轉為高范圍數據類型,即向上轉型。這個過程將會發生自動拆箱。

  • Java 中向上轉型并不需要添加任何轉化,但是向下轉換必須強制添加類型轉換。

上述代碼轉化比較麻煩,我們先從字節碼上來看:

第一步,將 nullInteger拆箱。

第二步,將上一步的值轉為 long 類型,即 (long)nullInteger.intValue()。

第三步,由于表達式 2 變成了基本數據類型,表達式 3 為包裝類型,根據案例 1 講到的規則,包裝類型需要轉為基本數據類型,所以表達式 3 發生了拆箱。

第四步,由于三目運算符最后的結果類型為基本數據類型:long,但是左邊類型為 Object,這里就需要把 long 類型裝箱轉為包裝類型。

所以最后代碼等同于:

  1. Object result = Long.valueOf(flag ? (long)nullInteger.intValue() : objLong.longValue()); 

總結

看完上述四個案例,想必大家應該會有種感受,沒想到這么簡單的三目運算符,既然暗藏這么多「殺機」。

不過大家也不用過度害怕,不使用三目運算符。只要我們在開發過程重點注意包裝類型的自動拆箱問題就好了,另外也要注意三目運算符的計算結果再賦值的時候自動拆箱引發的 NPE 的問題。

最好大家在開發過程中,都遵守一定的規范,即保持表達式 2 與表達式 3 的類型一致,不讓 Java 編譯器有自動拆箱的機會。

建議大家沒事經常看下阿里出品的『Java 開發手冊』,在最新的「泰山版」就增加三目運算符的這一節規范。

ps:公號消息回復:『開發手冊』,獲取最新版的 Java 開發手冊。

最后一定要做好的單元測試,不要慣性思維,覺得這么簡單的一個東西,看起來根本不可能出錯的。

參考資料

[1]15.25 節: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

[2]§5.6.2: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

[3]§5.1.13: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.13

[4]§5.1.8: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.8

[5]Java 開發手冊》解讀:三目運算符為何會導致 NPE?: https://developer.aliyun.com/article/758784

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2022-07-06 11:47:27

JAVAfor循環

2018-06-26 15:00:24

Docker安全風險

2024-04-02 08:41:10

ArrayListSubList場景

2021-02-03 20:19:08

Istio流量網格

2025-07-23 10:13:57

2017-12-21 19:38:50

潤乾中間表

2021-01-14 05:08:44

編譯鏈接

2022-07-26 23:43:29

編程語言開發Java

2013-01-15 09:41:45

編程語言

2024-02-20 08:09:51

Java 8DateUtilsDate工具類

2023-11-13 08:49:54

2017-07-04 14:01:40

機房機柜

2017-07-12 08:20:32

閃存用途企業

2021-06-10 09:00:33

單例模式數據庫

2022-03-03 07:00:43

Mybatiswhere標簽

2018-12-11 12:58:20

CPU散熱器鰭片

2019-08-27 08:17:57

云計算安全云服務商

2017-06-16 16:16:36

庫存扣減查詢

2018-05-29 14:57:59

HashMap容量初始化

2025-05-26 09:30:00

SQL數據庫索引
點贊
收藏

51CTO技術棧公眾號

国精产品一区二区| 91精品国产91久久久久久最新| 日本中文字幕影院| 国产福利视频在线观看| 国产福利精品一区二区| 777精品视频| 婷婷国产成人精品视频| 精品国产一区二区三区不卡蜜臂| 色婷婷综合久久久| 四虎4hu永久免费入口| 清纯唯美亚洲色图| 国产精品主播直播| 日韩美女福利视频| 久一视频在线观看| 色狮一区二区三区四区视频| 亚洲国产小视频| 特级西西444www| 欧亚一区二区| 精品国产31久久久久久| 大地资源第二页在线观看高清版| 日夜干在线视频| 国产69精品久久99不卡| 国产日韩一区在线| 日本黄色一级视频| 亚洲国产日本| 欧美插天视频在线播放| 青青青视频在线免费观看| 亚洲国产合集| 欧美精品一区二| 4438x全国最大成人| 久久er热在这里只有精品66| 色久综合一二码| 99在线精品免费视频| 超碰超碰在线| 国产精品天干天干在线综合| 欧美久久在线| 亚洲色偷精品一区二区三区| 高清国产一区二区三区| 91久久中文字幕| 亚洲天堂手机版| 免费视频一区二区| 国产国语刺激对白av不卡| 日本少妇激情视频| 欧美日韩一卡| 欧美大片免费观看在线观看网站推荐 | 免费av在线网址| 国产日韩v精品一区二区| 国内精品国语自产拍在线观看| 国产黄色大片网站| 国产精品亚洲午夜一区二区三区 | a在线观看视频| 国内精品免费在线观看| 91精品在线观| 国产美女无遮挡永久免费| 美女视频网站久久| 成人黄色生活片| 在线观看国产精品入口男同| 另类人妖一区二区av| 国产在线观看精品一区二区三区| 亚洲综合免费视频| 国产一区二区在线视频| **亚洲第一综合导航网站| 国产高潮流白浆喷水视频| 国产91精品入口| 精品国产乱码久久久久久蜜柚| 五月婷婷激情在线| 久久五月婷婷丁香社区| 色一情一乱一伦一区二区三欧美 | 亚洲亚洲免费| 在线视频中文亚洲| 尤物在线免费视频| 在线看片日韩| 国产成人自拍视频在线观看| 看黄色一级大片| 久久91精品国产91久久小草| 96久久精品| 五月婷中文字幕| 国产偷国产偷精品高清尤物| 一级一片免费播放| 91九色在线看| 日本韩国欧美一区二区三区| 久久久久久久久久一区| 亚洲码欧美码一区二区三区| 亚洲精品国产精品久久清纯直播| 无码 人妻 在线 视频| 视频在线不卡免费观看| 色综合久综合久久综合久鬼88 | 强迫凌虐淫辱の牝奴在线观看| 亚洲天堂日韩在线| 久久人人爽亚洲精品天堂| 欧美激情精品久久| 天堂精品中文字幕在线| 成人伊人精品色xxxx视频| 手机看片一区二区| 国产精品网友自拍| 亚洲人精品午夜射精日韩| 成人深夜福利| 亚洲国产精品久久久久久| 毛片aaaaaa| 在线欧美亚洲| 成人免费视频网址| 艳母动漫在线看| 自拍偷拍国产精品| 欧美日韩在线不卡视频| 精品精品视频| 一本色道久久综合狠狠躁篇怎么玩| 免费毛片在线播放免费| 视频精品一区二区| 国产精品中出一区二区三区| 日本在线人成| 色呦呦网站一区| 国产综合内射日韩久| 日韩毛片视频| 日韩av大片在线| 开心激情综合网| 亚洲男人天堂av| 一区二区成人网| 亚洲bt欧美bt精品777| 精品自在线视频| 伊人网综合在线| 久久亚洲私人国产精品va媚药| 青青草视频在线视频| 天天综合在线观看| 亚洲三级 欧美三级| 日本三级网站在线观看| 国产成a人无v码亚洲福利| 色就是色欧美| 麻豆精品蜜桃| 亚洲欧美成人在线| 日韩成人在线免费视频| 国产成人在线观看免费网站| 美国av在线播放| 免费成人毛片| 中文字幕日韩欧美在线| 国产精品免费无遮挡无码永久视频| 大桥未久av一区二区三区中文| 永久免费网站视频在线观看| 亚洲人体在线| 日韩视频第一页| 亚洲一级片免费看| 国产精品系列在线| 国产成人精品视频ⅴa片软件竹菊| 99re8这里有精品热视频8在线| 免费91在线视频| 国产精品自偷自拍| 18成人在线视频| 久久婷婷综合色| 色天天综合网| 91在线高清免费观看| 黄色免费在线看| 欧美一区中文字幕| 欧美日韩免费一区二区| 风流少妇一区二区| 男人添女荫道口女人有什么感觉| 亚洲图色一区二区三区| 欧美精品电影免费在线观看| 亚洲欧美另类综合| 欧美日韩国产在线播放| 黑人巨大精品欧美| 日韩精品免费视频人成| 亚洲乱码一区二区三区| 国产精品2区| 欧美极品少妇xxxxⅹ免费视频| 丁香花免费高清完整在线播放| 亚洲aaa精品| 熟妇高潮精品一区二区三区| 日韩电影免费在线| 一区二区精品在线| 日韩精品一区二区三区中文| 久久久在线视频| 美女做暖暖视频免费在线观看全部网址91 | 久久成人av网站| 亚洲精品久久久久久动漫器材一区| 亚洲一区二区四区蜜桃| 精品人妻少妇嫩草av无码| 日韩高清一级片| 熟女熟妇伦久久影院毛片一区二区| 久久伊人久久| 97色在线视频观看| 成人18在线| 欧美一二三四区在线| 国产午夜久久久| 国产亚洲一区二区三区四区| 在线视频观看一区二区| 在线精品亚洲| 亚洲在线欧美| 久久久久高潮毛片免费全部播放| 国产成人高清激情视频在线观看| 18videosex性欧美麻豆| 日韩精品极品毛片系列视频| 在线观看黄色国产| 午夜精品久久久久久久99樱桃| 亚洲综合第一区| 成人在线视频一区二区| 亚洲最大综合网| 亚洲国产日韩欧美一区二区三区| 神马影院午夜我不卡| 91精品久久久久久综合五月天| 日韩av电影手机在线观看| 18av在线视频| 中文字幕亚洲一区| 香港一级纯黄大片| 91精品国产一区二区三区蜜臀| 日韩精品一区二区亚洲av| 亚洲精品午夜久久久| 新91视频在线观看| 不卡欧美aaaaa| av中文字幕网址| 久久久久国内| 日韩国产成人无码av毛片| 久久香蕉国产| 区一区二区三区中文字幕| 澳门成人av| 国产三级精品网站| 成人在线爆射| 欧美亚洲一级片| 日本电影在线观看| 久久久国产精品免费| 国产精品四虎| 亚洲美女视频网| 少妇高潮一区二区三区69| 91超碰这里只有精品国产| 天天爱天天做天天爽| 性做久久久久久免费观看欧美| 任我爽在线视频| 中文字幕免费在线观看视频一区| 黄色性生活一级片| 成人免费毛片片v| 97免费公开视频| 精品写真视频在线观看| 日日噜噜噜噜久久久精品毛片| 国产精品资源| 精品国产一二三四区| 亚洲精品色图| 免费av观看网址| 一区二区三区国产在线| 六月婷婷在线视频| 在线不卡欧美| 日本人体一区二区| 在线播放精品| 日本丰满少妇xxxx| 日韩午夜在线电影| 久久久久久久中文| 亚洲在线电影| 波多野结衣50连登视频| 国产一区二区三区的电影 | 美女在线一区二区| 污网站免费在线| 日本aⅴ亚洲精品中文乱码| av无码精品一区二区三区| 肉色丝袜一区二区| 亚洲免费av一区二区三区| 日韩成人免费电影| 一区二区三区免费播放| 久久综合综合久久综合| 亚洲精品永久视频| 国产精品综合二区| 国产伦理在线观看| 成人av网站免费| 亚洲av无码一区二区二三区| 久久亚洲一级片| 婷婷丁香综合网| 亚洲精品一卡二卡| 日韩精品在线免费看| 欧美午夜久久久| 国产精品露脸视频| 3atv在线一区二区三区| 超碰福利在线观看| 精品亚洲va在线va天堂资源站| 精品福利视频导航大全| 日韩视频在线免费观看| 色帝国亚洲欧美在线| 欧美野外猛男的大粗鳮| 久久夜夜久久| 国产厕所精品在线观看| 午夜精品影视国产一区在线麻豆| 日韩av一区二区三区美女毛片| 97人人精品| 91动漫在线看| 日韩主播视频在线| av地址在线观看| 久久天天做天天爱综合色| 亚洲精品自拍视频在线观看| 亚洲国产aⅴ天堂久久| 波多野结衣大片| 欧美一级免费观看| 每日更新av在线播放| 久久国产精品久久久久久| 日韩脚交footjobhd| 成人h猎奇视频网站| 久久亚洲道色| 特级毛片在线免费观看| 亚洲女人av| 九九热视频免费| 91女神在线视频| 18岁成人毛片| 在线视频一区二区免费| 成人乱码一区二区三区| 色天天综合狠狠色| 碰碰在线视频| 亚洲自拍偷拍一区| 国产欧美日韩精品高清二区综合区| 无码人妻精品一区二区蜜桃百度| 日韩高清不卡一区| 成人在线电影网站| 国产精品电影院| 亚洲精品男人的天堂| 日韩欧美色电影| 午夜视频成人| 国产91免费观看| 国产色噜噜噜91在线精品| 在线码字幕一区| 日韩av中文字幕一区二区 | av官网在线观看| 伊人久久久久久久久久久| 国产高清不卡二三区| 国产精品二区在线| 国产探花在线精品| 日韩在线观看a| 蜜臀久久99精品久久久久宅男 | 亚洲毛片在线免费观看| 天堂av在线电影| 成人精品久久久| 成人av二区| 农村妇女精品一二区| 成人国产亚洲欧美成人综合网| 久久国产高清视频| 欧美日韩一卡二卡三卡| 国产女主播在线直播| 欧美一区第一页| 精品午夜电影| 日韩欧美国产综合在线| 丁香天五香天堂综合| 三级影片在线看| 欧美一区二区三区婷婷月色| 黄色网址在线免费播放| 国产裸体写真av一区二区 | 人妻少妇精品无码专区二区| 国产精品一卡二卡| 精品人妻伦九区久久aaa片| 欧美天堂一区二区三区| jizz亚洲| 国产精品视频一区国模私拍| 欧美在线观看视频一区| 国产v亚洲v天堂无码久久久 | 日本欧洲国产一区二区| 国产亚洲精品v| asian性开放少妇pics| 欧美性xxxx在线播放| 日本中文字幕电影在线观看| 57pao国产成人免费| 日韩动漫一区| 日本一极黄色片| 国产欧美精品一区二区三区四区 | 日本在线不卡一区| 国产传媒在线看| 欧美狂野另类xxxxoooo| 国产人成网在线播放va免费| 91在线短视频| 亚洲伦伦在线| 一级黄色片大全| 欧美日韩一区二区在线观看| 老司机在线永久免费观看| 999视频在线免费观看| 在线观看视频免费一区二区三区| www.17c.com喷水少妇| 日韩欧美视频一区二区三区| 成人在线播放视频| 91免费观看| 国产欧美日韩综合一区在线播放 | 亚洲伦在线观看| 亚洲免费黄色片| 国产成人综合精品| 羞羞色午夜精品一区二区三区| 国产吃瓜黑料一区二区| 色综合中文综合网| av电影在线网| eeuss一区二区三区| 国产日韩综合| 日本午夜精品视频| 精品国产免费人成在线观看| 国产v综合v| 麻豆md0077饥渴少妇| 成人一区在线观看| 精品不卡一区二区| 美女国内精品自产拍在线播放| 久久中文资源| 污网站免费在线| 午夜精品福利久久久| 1024免费在线视频| 国产精品免费一区二区三区四区| 日本三级亚洲精品| 久久久精品99| 国产亚洲视频在线| 澳门久久精品| 国产成人美女视频| 欧美日韩免费看| 日韩另类在线| 亚洲精品永久www嫩草| eeuss国产一区二区三区|