摘要:對(duì)支持的實(shí)現(xiàn)原理感興趣的原因,是在跟組員探討線上的一個(gè)空指針異常來的,以前根本沒意識(shí)到小小的還有這樣的玩法。這里我們定義參數(shù),根據(jù)值跳轉(zhuǎn)不同的邏輯。在我看來,代碼的脆弱多數(shù)是研發(fā)人員的代碼風(fēng)格不規(guī)范導(dǎo)致。
在 switch-case 語句的條件判斷中,或許使用整形或者枚舉更好,但由于種種歷史原因,項(xiàng)目中已大量使用字符串的情況下,只得硬著皮頭往前沖了。對(duì) switch 支持 String 的實(shí)現(xiàn)原理感興趣的原因,是在跟組員探討線上的一個(gè)空指針異常來的,以前根本沒意識(shí)到小小的switch 還有這樣的玩法。
要對(duì) switch 的原理追根溯源,我們來寫一段簡(jiǎn)單的 switch 代碼,反編譯來看看字節(jié)碼層是什么效果。
public class Testk { public static void main(String[] args) { String key = null; switch (key) { case "java": System.out.println("caught java"); break; case "android": System.out.println("caught android"); break; } } }
這里我們定義參數(shù)key,根據(jù) key 值跳轉(zhuǎn)不同的 case 邏輯。
正常情況下,使用 “javac <.java> ”生成.class 文件,使用“javap -verbose <.class>”即可得到字節(jié)碼,但由于javap得到的字節(jié)碼結(jié)構(gòu)難以理解,這里我們使用 JD-Gui 工具來查看。
Mac 下安裝JD-Gui工具
brew cask install jd-gui
把*.class 文件拖入打開的 JD-Gui窗口,即可得到如下結(jié)果:
import java.io.PrintStream; public class Testk { public static void main(String[] paramArrayOfString) { Object localObject1 = null; Object localObject2 = localObject1;int i = -1; switch (((String)localObject2).hashCode()) { case 3254818: if (((String)localObject2).equals("java")) { i = 0; } break; case -861391249: if (((String)localObject2).equals("android")) { i = 1; } break; } switch (i) { case 0: System.out.println("caught java"); break; case 1: System.out.println("caught android"); } } }
通過編譯后的代碼,我們知道 switch 處理字符串是先獲取hashCode ->equals()來實(shí)現(xiàn)的。
看到這里,我們明白文首的空指針是怎么來的了,編譯器針對(duì) switch 的 String 做編譯處理時(shí), 需要針對(duì) key 做做非空校驗(yàn)
另外,這里先基于 hashCode()再 equals()方法進(jìn)行安全檢查是有必要的,用來避免 hash 碰撞。
網(wǎng)上很多人都不建議使用字符串,給出的理由多半是String 的大小寫使得代碼更脆弱。在我看來,代碼的脆弱多數(shù)是研發(fā)人員的代碼風(fēng)格不規(guī)范導(dǎo)致。
就拿上面的代碼片段來說,改成全局定義變量即可解決大小寫敏感問題。
public class Testk { private static final String KEY_JAVA=“java”; private static final String KEY_ANDROID=“android”; public static void main(String[] args) { String key = null; switch (key) { case KEY_JAVA: System.out.println("caught java"); break; case KEY_ANDROID: System.out.println("caught java"); break; } } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72345.html
摘要:定義首先呢,我們來看一下單一職責(zé)原則的定義。只負(fù)責(zé)一項(xiàng)職責(zé),這就是單一職責(zé)原則。這時(shí)候就涉及到平衡的問題,平衡單一職責(zé)原則與修改造成的開銷。嘻哈說接下來,請(qǐng)您欣賞單一職責(zé)原則的原創(chuàng)歌曲。 showImg(https://segmentfault.com/img/remote/1460000016523263?w=600&h=350); 1、定義 首先呢,我們來看一下單一職責(zé)原則的定義。...
摘要:網(wǎng)絡(luò)協(xié)議解析我們來仔細(xì)看一下網(wǎng)絡(luò)的協(xié)議,真的非常復(fù)雜。控制面協(xié)議其中虛線部分是控制面的協(xié)議。這也是傳輸層的協(xié)議,也是面向連接的,但是更加適合移動(dòng)網(wǎng)絡(luò)。第二端是從到,通過協(xié)議知道自己是其中一端,并主動(dòng)通過協(xié)議,告訴它是隧道的另一端。 前面都是講電腦上網(wǎng)的情景,今天我們就來認(rèn)識(shí)下使用最多的移動(dòng)網(wǎng)絡(luò)上網(wǎng)場(chǎng)景。 移動(dòng)網(wǎng)絡(luò)的發(fā)展歷程 ????你一定知道手機(jī)上網(wǎng)有 2G、3G、4G 的說法,究竟這...
摘要:要注意這里的一個(gè)狀態(tài)行為因?yàn)檫@個(gè)詞是狀態(tài)模式中最重要的個(gè)概念??紤]到這點(diǎn),聰明的在中推出了狀態(tài)機(jī)這個(gè)偽函數(shù),能夠幫助我們快速實(shí)現(xiàn)狀態(tài)化。這里就引入了狀態(tài)機(jī)這個(gè)概念,以及和他對(duì)應(yīng)的狀態(tài)表。 ?首先聲明一點(diǎn),這個(gè)模式是我目前見過最好用(本人觀點(diǎn)),但是也是最難理解的一個(gè)(本人觀點(diǎn))。 所以大家需要做好心理準(zhǔn)備,如果,對(duì)這個(gè)模式?jīng)]有特別強(qiáng)烈的需求,比如: 我有一個(gè)Button,我按次數(shù)點(diǎn)擊它...
閱讀 2376·2023-04-25 20:07
閱讀 3311·2021-11-25 09:43
閱讀 3671·2021-11-16 11:44
閱讀 2537·2021-11-08 13:14
閱讀 3185·2021-10-19 11:46
閱讀 902·2021-09-28 09:36
閱讀 2997·2021-09-22 10:56
閱讀 2382·2021-09-10 10:51