淺談JAVA最常見(jiàn)的裝箱/拆箱坑
1. Integer / Long 判等用 ==
Integer a = 128; Integer b = 128; System.out.println(a == b); // false
很多人以為是 true,但這是比較“對(duì)象地址”,不是比較值。
正確寫(xiě)法:
Objects.equals(a, b)
或者:
a.equals(b)
但 a.equals(b) 要注意 a 不能為 null,所以更穩(wěn)的是:
Objects.equals(a, b)
這個(gè)坑在 Long id、Integer status 上特別常見(jiàn)。
2. 包裝類型和基本類型比較觸發(fā)拆箱,null 會(huì)空指針
Integer status = null;
if (status == 1) {
...
}
這會(huì)報(bào) NullPointerException。 因?yàn)樗鼤?huì)自動(dòng)拆箱成:
status.intValue() == 1
更安全的寫(xiě)法:
Integer.valueOf(1).equals(status)
或者:
Objects.equals(status, 1)
3. Boolean 當(dāng)成 boolean 用,null 會(huì)炸
Boolean deleted = null;
if (deleted) {
...
}
這也會(huì)空指針。因?yàn)?Java 會(huì)自動(dòng)拆箱:
if (deleted.booleanValue()) {
...
}
安全寫(xiě)法:
Boolean.TRUE.equals(deleted)
如果判斷 false:
Boolean.FALSE.equals(deleted)
這個(gè)在配置項(xiàng)、開(kāi)關(guān)字段里特別常見(jiàn)。
4. 數(shù)據(jù)庫(kù)字段是 Integer / Long,直接賦給基本類型
Integer dbValue = null; int value = dbValue;
這會(huì)空指針,因?yàn)檫@里發(fā)生了拆箱。
正確做法:
int value = dbValue == null ? 0 : dbValue;
或者保持包裝類型:
Integer value = dbValue;
如果數(shù)據(jù)庫(kù)字段允許為空,Java 實(shí)體通常就應(yīng)該用包裝類型,不要用基本類型。
5. 集合里必須用包裝類型,不能用基本類型
這個(gè)不算坑,但很常見(jiàn)
List<int> ids = new ArrayList<>();
這是錯(cuò)的,Java 泛型不能用基本類型。
只能寫(xiě):
List<Integer> ids = new ArrayList<>();
這里就涉及自動(dòng)裝箱/拆箱,比如:
ids.add(1); // 自動(dòng)裝箱成 Integer int x = ids.get(0); // 自動(dòng)拆箱成 int
如果 ids.get(0) 返回 null,這里也可能炸。
6. 三元表達(dá)式里混用包裝類型和基本類型
Integer a = null; int b = true ? a : 0;
這個(gè)也可能空指針,因?yàn)?nbsp;a 會(huì)被拆箱成 int。
這種代碼在“默認(rèn)值處理”時(shí)很容易寫(xiě)出來(lái)。更穩(wěn)的寫(xiě)法:
int b = a == null ? 0 : a;
7. Stream / Lambda 里隱式拆箱
List<Integer> list = Arrays.asList(1, 2, null, 4); int sum = list.stream().mapToInt(Integer::intValue).sum();
這里如果有 null,會(huì)直接空指針。
安全一點(diǎn)要先過(guò)濾:
int sum = list.stream()
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
8. 狀態(tài)字段來(lái)自數(shù)據(jù)庫(kù),直接 switch 或運(yùn)算
Integer status = null;
switch (status) {
case 1 -> ...
}
這也會(huì)因?yàn)椴鹣鋱?bào)錯(cuò)。
所以狀態(tài)字段如果可能為 null,先判空再處理。
項(xiàng)目里幾個(gè)實(shí)用的建議
- Long、Integer、Boolean 比較值時(shí),優(yōu)先用 Objects.equals(...)
- 狀態(tài)判斷常量寫(xiě)左邊,比如:
Integer.valueOf(1).equals(status)
- Boolean 判斷優(yōu)先寫(xiě):
Boolean.TRUE.equals(flag)
- 數(shù)據(jù)庫(kù)可空字段,Java 實(shí)體盡量用包裝類型,不要用基本類型
- 只要看到 == 1、== 0、if (flag),就要想一下會(huì)不會(huì)拆箱
到此這篇關(guān)于淺談JAVA最常見(jiàn)的裝箱/拆箱坑的文章就介紹到這了,更多相關(guān)JAVA 裝箱/拆箱坑內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea?maven依賴引入失效無(wú)法正常導(dǎo)入依賴問(wèn)題的解決方法
有時(shí)候idea導(dǎo)入一個(gè)新項(xiàng)目,或者pom文件修改(新增)了依賴,pom文件和代碼會(huì)報(bào)紅,提示依賴包不存在,下面這篇文章主要給大家介紹了關(guān)于idea?maven依賴引入失效無(wú)法正常導(dǎo)入依賴問(wèn)題的解決方法,需要的朋友可以參考下2023-04-04
基于Java編寫(xiě)一個(gè)實(shí)用的ExcelUtil工具類
在項(xiàng)目中經(jīng)常遇到excel表格導(dǎo)入導(dǎo)出功能,每次都要重復(fù)寫(xiě)有關(guān)excel 的邏輯,所以本文直接使用Java編寫(xiě)一個(gè)實(shí)用的ExcelUtil工具類,希望對(duì)大家有所幫助2024-04-04
解決spring-data-jpa 事物中修改屬性自動(dòng)更新update問(wèn)題
這篇文章主要介紹了解決spring-data-jpa 事物中修改屬性自動(dòng)更新update問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家2021-08-08
JAVA項(xiàng)目如何打包部署到Linux服務(wù)器上
本文詳細(xì)介紹了在服務(wù)器上部署環(huán)境包括JDK、MySQL、Tomcat的設(shè)置,以及使用Idea-Maven-SpringBoot進(jìn)行jar包打包部署的流程,內(nèi)容涵蓋了MySQL配置注意事項(xiàng)、pom.xml配置、打包命令等關(guān)鍵步驟,同時(shí),也提供了如何將jar包上傳到Linux服務(wù)器并運(yùn)行的具體方法2024-10-10
java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解
這篇文章主要為大家介紹了java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Java SpringMVC 集成靜態(tài)資源的方式你了解嗎
本篇文章主要介紹了SpringMVC集成靜態(tài)資源的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-10-10
Spring Cloud Alibaba Nacos Config進(jìn)階使用
這篇文章主要介紹了Spring Cloud Alibaba Nacos Config進(jìn)階使用,文中使用企業(yè)案例,圖文并茂的展示了Nacos Config的使用,感興趣的小伙伴可以看一看2021-08-08

