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