為什么阿里建議對(duì) switch 括號(hào)內(nèi)的 String 變量進(jìn)行判空?
共 8396字,需瀏覽 17分鐘
·
2024-08-16 14:17
來源:juejin.cn/post/7295575713343537167
?? 歡迎加入小哈的星球,你將獲得: 專屬的項(xiàng)目實(shí)戰(zhàn) / 1v1 提問 / Java 學(xué)習(xí)路線 / 學(xué)習(xí)打卡 / 每月贈(zèng)書 / 社群討論
新項(xiàng)目:《從零手?jǐn)]:仿小紅書(微服務(wù)架構(gòu))》 正在持續(xù)爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 點(diǎn)擊查看項(xiàng)目介紹; 《從零手?jǐn)]:前后端分離博客項(xiàng)目(全棧開發(fā))》 2期已完結(jié),演示鏈接:http://116.62.199.48/; 截止目前,累計(jì)輸出 53w+ 字,講解圖 2330+ 張,還在持續(xù)爆肝中.. 后續(xù)還會(huì)上新更多項(xiàng)目,目標(biāo)是將 Java 領(lǐng)域典型的項(xiàng)目都整一波,如秒殺系統(tǒng), 在線商城, IM 即時(shí)通訊,Spring Cloud Alibaba 等等,戳我加入學(xué)習(xí),解鎖全部項(xiàng)目,已有1900+小伙伴加入
![]()
-
引言 -
變量類型為String -
外部參數(shù) -
總結(jié)
引言
空指針NullPointerException可以說是開發(fā)中最經(jīng)常碰到的異常了。良好的代碼規(guī)范可以規(guī)避掉一些這樣的異常。在《阿里巴巴規(guī)范手冊(cè)》中有這樣一條規(guī)范:
我們可以從這句話得出兩個(gè)前置條件:
-
switch括號(hào)內(nèi)的變量類型為String。 -
此變量為外部參數(shù)時(shí)。
變量類型為String
你知道這行代碼輸出什么嗎?
public class SwitchString {
public static void main(String[] args) {
method (null);
}
public static void method(String param) {
switch (param) {
// 肯定不是進(jìn)入這里
case "sth":
System.out.println("it's sth");
break;
// 也不是進(jìn)入這里
case "null":
System.out.println("it's null");
break;
// 也不是進(jìn)入這里
default:
System.out.println("default");
}
}
}
如果我們不看上面的注釋,你會(huì)認(rèn)為程序會(huì)打印出哪句話呢?我們點(diǎn)擊運(yùn)行,報(bào)了NullPointerException空指針異常~
Exception in thread "main" java.lang.NullPointerException
at SwitchString.method(SwitchString.java:8)
at SwitchString.main(SwitchString.java:4)
很奇怪,為啥會(huì)空指針呢? 你可能會(huì)說第8行param為空,所以空指針了。雖然這樣理解也沒問題。
我們要知道,NPE異常是代碼中使用了這個(gè)對(duì)象的某些方法或者屬性,而這個(gè)對(duì)象為空所以就會(huì)拋出異常。例如以下代碼
public class TestNPE {
private int id;
public static void main(String[] args) {
TestNPE testNPE = null;
System.out.println(testNPE);
System.out.println(testNPE.id);
}
}
我們點(diǎn)擊運(yùn)行可以得知。雖然testNPE這個(gè)對(duì)象為null,但是我們對(duì)其打印是沒有問題的,但如果涉及到了對(duì)這個(gè)對(duì)象的某些方法或者屬性的調(diào)用就會(huì)報(bào)錯(cuò)。
null
Exception in thread "main" java.lang.NullPointerException
at TestNPE.main(TestNPE.java:8)
而我們上面那個(gè)例子,它是在哪里使用了這個(gè)對(duì)象呢?
其實(shí)swtich是Java中的一個(gè)語(yǔ)法糖。
JDK7之前switch本身只支持基本類型,JDK7開始支持String。
Java中的switch自身原本就支持基本類型。比如int、char等。對(duì)于int類型,直接進(jìn)行數(shù)值的比較。對(duì)于char類型則是比較其ascii碼。所以,對(duì)于編譯器來說,switch中其實(shí)只能使用整型,任何類型的比較都要轉(zhuǎn)換成整型。比如byte。short,char(ackii碼是整型)以及int。
我們將上面的代碼進(jìn)行反編譯可以得到
public class SwitchString {
public static void main(String[] args) {
method((String)null);
}
public static void method(String param) {
byte var2 = -1;
switch(param.hashCode()) {
case 114215:
if(param.equals("sth")) {
var2 = 0;
}
break;
case 3392903:
if(param.equals("null")) {
var2 = 1;
}
}
switch(var2) {
case 0:
System.out.println("it's sth");
break;
case 1:
System.out.println("it's null");
break;
default:
System.out.println("default");
}
}
}
字符串的switch是通過equals()和hashCode()方法來實(shí)現(xiàn)的。由于調(diào)用了這兩個(gè)方法,而param為null,所以出現(xiàn)了空指針異常。
外部參數(shù)
那么為啥還要是外部參數(shù)呢?其實(shí)很簡(jiǎn)單,我們把代碼修改一下:
public class SwitchString {
public static void main(String[] args) {
switch (null) {
// 肯定不是進(jìn)入這里
case "sth":
System.out.println("it's sth");
break;
// 也不是進(jìn)入這里
case "null":
System.out.println("it's null");
break;
// 也不是進(jìn)入這里
default:
System.out.println("default");
}
}
}
這樣的代碼是會(huì)報(bào)錯(cuò)提示的且編譯是無法通過。~~
總結(jié)
我們對(duì)switch這種情況進(jìn)行了分析,得出了兩個(gè)條件:
-
switch括號(hào)內(nèi)的變量類型為String。 -
此變量為外部參數(shù)時(shí)。
條件1是String類型的變量參數(shù)對(duì)象的判斷是通過equals()和hashCode()方法來實(shí)現(xiàn)的。所以變量參數(shù)為null,調(diào)用這兩個(gè)方法就會(huì)出現(xiàn)NPE。
條件2則是編譯器會(huì)幫我們檢查并且這是不符合語(yǔ)法的不能進(jìn)行編譯。
?? 歡迎加入小哈的星球,你將獲得: 專屬的項(xiàng)目實(shí)戰(zhàn) / 1v1 提問 / Java 學(xué)習(xí)路線 / 學(xué)習(xí)打卡 / 每月贈(zèng)書 / 社群討論
新項(xiàng)目:《從零手?jǐn)]:仿小紅書(微服務(wù)架構(gòu))》 正在持續(xù)爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 點(diǎn)擊查看項(xiàng)目介紹; 《從零手?jǐn)]:前后端分離博客項(xiàng)目(全棧開發(fā))》 2期已完結(jié),演示鏈接:http://116.62.199.48/; 截止目前,累計(jì)輸出 53w+ 字,講解圖 2330+ 張,還在持續(xù)爆肝中.. 后續(xù)還會(huì)上新更多項(xiàng)目,目標(biāo)是將 Java 領(lǐng)域典型的項(xiàng)目都整一波,如秒殺系統(tǒng), 在線商城, IM 即時(shí)通訊,Spring Cloud Alibaba 等等,戳我加入學(xué)習(xí),解鎖全部項(xiàng)目,已有1900+小伙伴加入
![]()
3. 架構(gòu)設(shè)計(jì)中如何應(yīng)對(duì)接口級(jí)故障?
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過內(nèi)容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標(biāo)”,這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。
點(diǎn)“在看”支持小哈呀,謝謝啦
