成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

三目運算符的空指針問題,終于被阿里巴巴開發手冊收錄

開發 開發工具
最近,阿里巴巴Java開發手冊發布了最新版,泰山版,這個名字起的不錯,一覽眾山小。新版據說新增了30+規約,我還沒來得及仔細去看,不過有粉絲和我說,其中新增的一條規約,他之前在我的博客中看到過。

[[324164]]

最近,阿里巴巴Java開發手冊發布了最新版,泰山版,這個名字起的不錯,一覽眾山小。

新版據說新增了30+規約,我還沒來得及仔細去看,不過有粉絲和我說,其中新增的一條規約,他之前在我的博客中看到過。

仔細看了下,這個問題確實我很久之前遇到過,確實曾經在博客中也記錄過。

最初遇到這個問題的是我的同事,他在代碼中使用了三目運算符,代碼在線上運行的時候發生了NPE,經過排查,發現原來是三目運算符和自動拆裝箱之間有一定的關系,導致了空指針。

這篇文章最開始發布于2015年,目前已經有1w+閱讀量了。

 

趁著最新的開發手冊中也提到了這個點,于是把之前的文章內容翻出來并重新整理了一下,帶大家一起回顧下這個知識點。

一、三目運算符

對于條件表達式b?x:y,先計算條件b,然后進行判斷。如果b的值為true,計算x的值,運算結果為x的值;否則,計算y的值,運算結果為y的值。一個條件表達式從不會既計算x,又計算y。條件運算符是右結合的,也就是說,從右向左分組計算。例如,a?b:c?d:e將按a?b:(c?d:e)執行。

二、自動裝箱與自動拆箱

基本數據類型的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。

一般我們要創建一個類的對象實例的時候,我們會這樣:Class a = new Class(parameters);

當我們創建一個Integer對象時,卻可以這樣:Integer i = 100;(注意:和 int i = 100;是有區別的)

實際上,執行上面那句代碼的時候,系統為我們執行了:Integer i = Integer.valueOf(100);

這里暫且不討論這個原理是怎么實現的(何時拆箱、何時裝箱),也略過普通數據類型和對象類型的區別。

我們可以理解為,當我們自己寫的代碼符合裝(拆)箱規范的時候,編譯器就會自動幫我們拆(裝)箱。

那么,這種不被程序員控制的自動拆(裝)箱會不會存在什么問題呢?

三、問題回顧

首先,通過你已有的經驗看一下下面這段代碼:

  1. Map<String,Boolean> map =  new HashMap<String, Boolean>();  
  2. Boolean b = (map!=null ? map.get("test") : false); 

以上這段代碼,是我們在不注意的情況下有可能經常會寫的一類代碼(在很多時候我們都愛使用三目運算符)。當然,這段代碼是存在問題的,執行該代碼,會報NPE.

  1. HashMap hashmap = new HashMap(); 
  2.  
  3. Boolean boolean1 = Boolean.valueOf(hashmap == null ? false : ((Boolean)hashmap.get("test")).booleanValue()); 

首先可以明確的是,既然報了空指針,那么一定是有些地方調用了一個null的對象的某些方法。

在這短短的兩行代碼中,看上去只有一處方法調用map.get("test"),但是我們也都是知道,map已經事先初始化過了,不會是Null,那么到底是哪里有空指針呢。

我們接下來反編譯一下該代碼。看看我們寫的代碼在經過編譯器處理之后變成了什么樣。

反編譯后代碼如下:

  1. HashMap hashmap = new HashMap(); 
  2.  
  3. Boolean boolean1 = Boolean.valueOf(hashmap == null ? false : ((Boolean)hashmap.get("test")).booleanValue()); 

看完這段反編譯之后的代碼之后,經過分析我們大概可以知道問題出在哪里。

((Boolean)hashmap.get("test")).booleanValue()的執行過程及結果如下:

  1. hashmap.get("test")->null
  2. (Boolean)null->null
  3. null.booleanValue()->報錯 

好,問題終于定位到了。那么接下來看看如何解決該問題以及為什么會出現這種問題。

四、原理分析

通過查看反編譯之后的代碼,我們準確的定位到了問題,分析之后我們可以得出這樣的結論:NPE的原因應該是三目運算符和自動拆箱導致了空指針異常。

根據規定,三目運算符的第二、第三位操作數的返回值類型應該是一樣的,這樣才能當把一個三目運算符的結果賦值給一個變量。

如:Person i = a>b ? i1:i2; ,就要求i1和i2的類型都必須是Person才行。

因為Java中存在一種特殊的情況,那就是基本數據類型和包裝數據類型可以通過自動拆裝箱的方式互相轉換。即可以定義int i = new Integer(10);也可以定義Integer i= 10;

那如果,三目運算符的第二位和第三位的操作數的類型分別是基本數據類型和包裝類型對象時,就需要有一方需要進行自動拆裝箱。

那到底如何做的呢,根據三目運算符的語法規范。參見jls-15.25,摘要如下:

  • 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.
  • If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

簡單的來說就是:當第二,第三位操作數分別為基本類型和對象時,其中的對象就會拆箱為基本類型進行操作。

所以,結果就是:由于使用了三目運算符,并且第二、第三位操作數分別是基本類型和對象。所以對對象進行拆箱操作,由于該對象為null,所以在拆箱過程中調用null.booleanValue()的時候就報了NPE。

五、問題解決

如果代碼這么寫,就不會報錯:

  1. Map<String,Boolean> map =  new HashMap<String, Boolean>(); 
  2.  
  3. Boolean b = (map!=null ? map.get("test") : Boolean.FALSE); 

就是保證了三目運算符的第二第三位操作數都為對象類型。

這和三目運算符有關。

關于作者:Hollis,一個對Coding有著獨特追求的人,現任阿里巴巴技術專家,個人技術博主,技術文章全網閱讀量數千萬,《程序員的三門課》聯合作者。

【本文是51CTO專欄作者Hollis的原創文章,作者微信公眾號Hollis(ID:hollischuang)】

 

戳這里,看該作者更多好文

 

責任編輯:武曉燕 來源: Hollis
相關推薦

2017-05-02 21:14:20

阿里巴巴Java開發

2020-05-06 12:24:57

NPE三目運算符

2018-04-27 15:30:53

Java三目運算符

2010-06-28 10:43:47

2020-12-18 10:55:51

阿里巴巴Redis數據庫

2025-04-17 08:47:23

2013-08-22 09:36:45

阿里巴巴王堅阿里云

2020-06-01 08:04:18

三目運算符代碼

2013-08-22 09:41:52

阿里巴巴去IOE王堅

2025-02-24 11:16:20

2020-10-18 10:47:22

空值合并運算符 '??

2015-07-30 09:31:26

阿里巴巴前端面試

2015-05-12 15:09:01

阿里巴巴公有云IaaS

2013-06-02 21:53:51

阿里巴巴Windows Azu淘寶

2015-11-05 11:29:05

2009-08-11 15:51:08

C#運算符算術運算符

2024-01-31 08:12:42

編程C++運算符

2019-08-15 10:25:02

代碼開發工具

2023-03-29 09:42:32

2009-02-27 10:46:32

DBA筆試題阿里巴巴
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品在线观看一区二区 | 亚洲精品丝袜日韩 | 九色综合网 | 韩日在线观看视频 | 久久久久www | 九热在线 | 成人在线免费电影 | 日本啊v在线 | 人人玩人人添人人澡欧美 | 成人高潮片免费视频欧美 | 日韩中文字幕在线视频观看 | 91av国产在线视频 | 91视频免费视频 | 国产综合在线视频 | 国产精品成人品 | 久久精品亚洲 | 欧美亚洲高清 | 午夜视频一区 | 免费观看一级特黄欧美大片 | 国内毛片毛片毛片毛片 | 国产一区二区在线观看视频 | 久久久久久久久久久成人 | 成人av片在线观看 | 成人精品在线观看 | 成人一区二 | av色在线 | 影音先锋欧美资源 | 综合色播 | 中文字幕人成乱码在线观看 | 国产色婷婷久久99精品91 | 成人精品视频 | 国产色网站 | 欧美久久国产精品 | 亚洲一级淫片 | 久久精品国产99国产精品 | 欧美成人免费电影 | 久久精品一级 | 天天干天天色 | 黄色高清视频 | 久一精品 | 欧美激情在线播放 |