"

德甲体育-欢迎您_YABO网页登陆-官网-欢迎您拥有全球最顶尖的原生APP,每天为您提供千场精彩体育赛事,德甲体育-欢迎您_YABO网页登陆-官网-欢迎您更有真人、彩票、电子老虎机、真人电子竞技游戏等多种娱乐方式选择,德甲体育-欢迎您_YABO网页登陆-官网-欢迎您让您尽享娱乐、赛事投注等,且无后顾之忧!

"
首頁 > 技術大佬:我去,你寫的 switch 語句也太老土了吧

技術大佬:我去,你寫的 switch 語句也太老土了吧

互聯網 2021-04-23 00:21:58

昨天早上通過遠程的方式 review 了兩名新來同事的代碼,大部分代碼都寫得很漂亮,嚴謹的同時注釋也很到位,這令我非常滿意。但當我看到他們當中有一個人寫的 switch 語句時,還是忍不住破口大罵:“我擦,小王,你丫寫的 switch 語句也太老土了吧!”

來看看小王寫的代碼吧,看完不要罵我裝逼啊。

private static String createPlayer(PlayerTypes playerType) {switch (playerType) {case TENNIS:return "網球運動員費德勒";case FOOTBALL:return "足球運動員C羅";case BASKETBALL:return "籃球運動員詹姆斯";case UNKNOWN:throw new IllegalArgumentException("未知");default:throw new IllegalArgumentException("運動員類型: " + playerType);}}

看完上述代碼后,你是不是會發出這樣的感慨——“代碼寫得很好,沒有任何問題??!”是不是覺得我在無事生非,錯怪了小王!但此時我要送上《了不起的蓋茨比》中的一句話:

我年紀還輕,閱歷不深的時候,我父親教導過我一句話,我至今還念念不忘。 “每逢你想要批評任何人的時候, ”他對我說,“你就記住,這個世界上所有的人,并不是個個都有過你擁有的那些優越條件?!?/p>

哈哈,這句話不光是讓你看的,也是給我看的。是時候冷靜下來談談上述 switch 語句的老土問題了。

看到上圖了吧,當不小心刪掉 default 語句后,編譯器就會報錯,提示:“沒有返回語句”,為了解決這個問題,我們可以新建一個 player 變量作為返回結果,就像下面這樣:

private static String createPlayer(PlayerTypes playerType) {String player = null;switch (playerType) {case TENNIS:player = "網球運動員費德勒";break;case FOOTBALL:player = "足球運動員C羅";break;case BASKETBALL:player = "籃球運動員詹姆斯";break;case UNKNOWN:throw new IllegalArgumentException("未知");}return player;}

當添加了 player 變量后,case 語句中就需要添加上 break 關鍵字;另外在 switch 語句結束后,返回 player。這時候,編譯器并不會提示任何錯誤,說明 default 語句在這種情況下是可以省略的。

從 JDK 12 開始(本例使用的是 JDK 13),switch 語句升級了,不僅可以像傳統的 switch 語句那樣作為條件的判斷,還可以直接作為一個返回結果。來對小王的代碼進行改造,如下所示:

private static String createPlayer(PlayerTypes playerType) { return switch (playerType) {case TENNIS -> "網球運動員費德勒";case FOOTBALL -> "足球運動員C羅";case BASKETBALL -> "籃球運動員詹姆斯";case UNKNOWN ->throw new IllegalArgumentException("未知");};}

夠 fashion 吧?不僅 switch 關鍵字之前加了 return 關鍵字,case 中還見到了 Lambda 表達式的影子,中劃線和箭頭替代了冒號,意味著箭頭右側的代碼只管執行無須 break。

并且,default 語句變成了可選項,可有可無,不信?你也動手試試。

新的 switch 語句足夠的智能化,除了有上述的 3 個優勢,還可以對枚舉類型的條件進行校驗。假如在 PlayerTypes 中增加了新的類型 PINGPANG(乒乓球):

public enum PlayerTypes {TENNIS,FOOTBALL,BASKETBALL,PINGPANG,UNKNOWN}

此時編譯器會發出以下警告:

意思就是 switch 中的 case 條件沒有完全覆蓋枚舉中可能存在的值。好吧,那就把 PINGPANG 的條件加上吧。來看一下完整的代碼:

public class OldSwitchDemo {public enum PlayerTypes {TENNIS,FOOTBALL,BASKETBALL,PINGPANG,UNKNOWN}public static void main(String[] args) {System.out.println(createPlayer(PlayerTypes.BASKETBALL));}private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> "網球運動員費德勒";case FOOTBALL -> "足球運動員C羅";case BASKETBALL -> "籃球運動員詹姆斯";case PINGPANG -> "乒乓球運動員馬龍";case UNKNOWN -> throw new IllegalArgumentException("未知");};}}

switch 語句變成了強大的 switch 表達式,美滋滋??!那假如一個運動員既會打籃球又會打乒乓球呢?

private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> "網球運動員費德勒";case FOOTBALL -> "足球運動員C羅";case BASKETBALL,PINGPANG -> "牛逼運動員沉默王二";case UNKNOWN -> throw new IllegalArgumentException("未知");};}

就像上述代碼那樣,使用英文逗號“,”把條件分割開就行了,666 ??!

不服氣?switch 表達式還有更厲害的,-> 右側還可以是 {} 括起來的代碼塊,就像 Lambda 表達式那樣。

private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> {System.out.println("網球");yield "網球運動員費德勒";}case FOOTBALL -> {System.out.println("足球");yield "足球運動員C羅";}case BASKETBALL -> {System.out.println("籃球");yield "籃球運動員詹姆斯";}case PINGPANG -> {System.out.println("乒乓球");yield "乒乓球運動員馬龍";}case UNKNOWN -> throw new IllegalArgumentException("未知");};}

細心的同學會發現一個之前素未謀面的關鍵字 yield,它和傳統的 return、break 有什么區別呢?

先來看官方的解釋:

A yield statement transfers control by causing an enclosing switch expression to produce a specified value.

意思就是說 yield 語句通過使一個封閉的 switch 表達式產生一個指定值來轉移控制權。為了進一步地了解 yield 關鍵字,我們可以反編譯一下字節碼:

private static String createPlayer(NewSwitchDemo3.PlayerTypes playerType) {String var10000;switch(playerType) {case TENNIS:System.out.println("網球");var10000 = "網球運動員費德勒";break;case FOOTBALL:System.out.println("足球");var10000 = "足球運動員C羅";break;case BASKETBALL:System.out.println("籃球");var10000 = "籃球運動員詹姆斯";break;case PINGPANG:System.out.println("乒乓球");var10000 = "乒乓球運動員馬龍";break;case UNKNOWN:throw new IllegalArgumentException("未知");default:throw new IncompatibleClassChangeError();}return var10000;}

編譯器在生成字節碼的時候對 yield 關鍵字做了自動化轉義,轉成了傳統的 break 語句。這下清楚了吧?

但是,話又說出來,那些看似 fashion 的代碼也不過是把部分秀技的工作交給了編譯器,還可能存在對舊版本不兼容、對隊友不友好的問題——代碼土點就土點唄,沒準是最實用的。

“不好意思,我為昨天早上的囂張向你道歉。。。。。?!蔽蚁蛐⊥醢l送了一條信息。

好了,我親愛的讀者朋友,以上就是本文的全部內容了,希望能夠博得你的歡心。

最后,一定會有不少讀者想要問我怎么學習 Java 的,那我干脆就把我看過的優質書籍貢獻出來:

1)入門版:《Head First Java》、《Java 核心技術卷》

2)進階版:《Java編程思想》、《Effective Java》、《Java網絡編程》、《代碼整潔之道》

3)大牛版:《Java并發編程》、《深入理解Java虛擬機》、《Java性能權威指南》、《重構》、《算法》

就先介紹這么多,希望對那些不知道看什么書的同學有所幫助。

對了,我介紹的這些書籍,已經順便幫你整理好了,你可以在我的原創微信公眾號『沉默王二』回復『書籍』獲取哦

有收獲?希望老鐵們來個三連擊,給更多的同學看到這篇文章
免責聲明:非本網注明原創的信息,皆為程序自動獲取互聯網,目的在于傳遞更多信息,并不代表本網贊同其觀點和對其真實性負責;如此頁面有侵犯到您的權益,請給站長發送郵件,并提供相關證明(版權證明、身份證正反面、侵權鏈接),站長將在收到郵件12小時內刪除。
德甲体育-欢迎您_YABO网页登陆-官网-欢迎您 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>