<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 14 新增 5 項(xiàng)新特性, 我還在用Java 8

          共 7364字,需瀏覽 15分鐘

           ·

          2020-08-22 01:17

          點(diǎn)擊“開發(fā)者技術(shù)前線”,選擇“星標(biāo)?”

          在看|星標(biāo)|留言,? 真愛

          作者 |?Raoul-Gabriel Urma
          譯者 |?彎月,責(zé)編 | 郭芮??出品 | CSDN(ID:CSDNnews)

          Java 14預(yù)定于3月17日發(fā)布。那么,14版究竟有什么新功能,對(duì)于整天寫代碼、維護(hù)代碼的Java開發(fā)者來說,哪些功能最有用呢?

          以下為譯文:

          第14版包含的JEP(Java Enhancement Proposals,Java增強(qiáng)提案)比12版和13版加起來還要多。在這篇文章中,我將主要討論以下幾點(diǎn):
          • 改進(jìn)的switch表達(dá)式,第一次出現(xiàn)在Java 12和13中,在Java 14中獲得了完全的支持

          • instanceof支持模式匹配(語言特性)

          • NullPointerException(JVM特性)

          希望你在閱讀完本文后,積極地代碼中實(shí)驗(yàn)這些功能,為Java團(tuán)隊(duì)提供反饋,并為Java的發(fā)展做出貢獻(xiàn)。


          Switch表達(dá)式
          Java 14中的switch表達(dá)式將會(huì)永久存在。如果你需要回憶一下什么是switch表達(dá)式,可以參考下以前這兩篇文章(https://blogs.oracle.com/javamagazine/new-switch-expressions-in-java-12,https://blogs.oracle.com/javamagazine/inside-java-13s-switch-expressions-and-reimplemented-socket-api)。
          在之前的發(fā)布中,switch表達(dá)式只是一個(gè)“預(yù)覽”階段的特性。我想提醒一下,“預(yù)覽”階段的特性的目的是為了收集反饋,這些特性可能會(huì)隨時(shí)改變,根據(jù)反饋結(jié)果,這些特性甚至可能會(huì)被移除,但通常所有預(yù)覽特性最后都會(huì)在Java中固定下來。
          新的switch表達(dá)式的優(yōu)點(diǎn)是,不再有缺省跳過行為(fall-through),更全面,而且表達(dá)式和組合形式更容易編寫,因此出現(xiàn)bug的可能性就更低。例如,switch表達(dá)式現(xiàn)在可以使用箭頭語法,如下所示:
          var log = switch (event) {    case PLAY -> "User has triggered the play button";    case STOP, PAUSE -> "User needs a break";    default -> {        String message = event.toString();        LocalDateTime now = LocalDateTime.now();        yield "Unknown event " + message +               " logged on " + now;    }};

          文本塊
          Java 13引入的一個(gè)預(yù)覽功能是文本塊。有了文本塊,多行的字符串字面量就很容易編寫了。這個(gè)功能在Java 14中進(jìn)行第二次預(yù)覽,而且發(fā)生了一些變化。例如,多行文本的格式化可能需要編寫許多字符串連接操作和轉(zhuǎn)義序列。下面的代碼演示了一個(gè)HTML的例子:
          String html = "" +"\n\t" + "" +"\n\t\t" + "

          \"Java 14 is here!\"

          " +
          "\n\t" + "" +"\n" + "";
          有了文本塊,就可以簡(jiǎn)化這一過程,只需使用三引號(hào)作為文本塊的起始和結(jié)束標(biāo)記,就能編寫出更優(yōu)雅的代碼:
          String html = """      

          "Java 14 is here!"

          """;
          與普通的字符串字面量相比,文本塊的表達(dá)性更好。更多的內(nèi)容可以參考這篇文章(https://blogs.oracle.com/javamagazine/text-blocks-come-to-java)。
          Java 14引入了兩個(gè)新的轉(zhuǎn)義序列。第一,可以使用新的 \s 轉(zhuǎn)義序列來表示一個(gè)空格。第二,可以使用反斜杠 \ 來避免在行尾插入換行字符。這樣可以很容易地在文本塊中將一個(gè)很長(zhǎng)的行分解成多行來增加可讀性。
          例如,現(xiàn)在編寫多行字符串的方式如下:
          String literal =          "Lorem ipsum dolor sit amet, consectetur adipiscing " +         "elit, sed do eiusmod tempor incididunt ut labore " +         "et dolore magna aliqua.";
          在文本塊中使用 \ 轉(zhuǎn)義序列,就可以寫成這樣:
          String text = """                Lorem ipsum dolor sit amet, consectetur adipiscing \                elit, sed do eiusmod tempor incididunt ut labore \                et dolore magna aliqua.\                """;


          instanceof的模式匹配

          Java 14引入了一個(gè)預(yù)覽特性,有了它就不再需要編寫先通過instanceof判斷再?gòu)?qiáng)制轉(zhuǎn)換的代碼了。例如,下面的代碼:
          if (obj instanceof Group) {  Group group = (Group) obj;
          // use group specific methods var entries = group.getEntries();}
          利用這個(gè)預(yù)覽特性可以重構(gòu)為:
          if (obj instanceof Group group) {  var entries = group.getEntries();}
          由于條件檢查要求obj為Group類型,為什么還要像第一段代碼那樣在條件代碼塊中指明obj為Group類型呢?這可能會(huì)引發(fā)錯(cuò)誤。
          這種更簡(jiǎn)潔的語法可以去掉Java程序里的大多數(shù)強(qiáng)制類型轉(zhuǎn)換。(2011年的一篇針對(duì)相關(guān)語言特性的研究論文(http://www.cs.williams.edu/FTfJP2011/6-Winther.pdf)指出,24%的類型轉(zhuǎn)換都來自于instanceof后的條件語句。)
          JEP 305解釋了這項(xiàng)改變,并給出了Joshuoa Bloch的著作《Effective Java》中的一個(gè)例子,演示了下面兩種等價(jià)的寫法:
          @Override public boolean equals(Object o) {     return (o instanceof CaseInsensitiveString) &&             ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); }
          這段代碼嗎中冗余的CaseInsensitiveString強(qiáng)制類型轉(zhuǎn)換可以去掉,轉(zhuǎn)換成下面的方式:
          @Override public boolean equals(Object o) {     return (o instanceof CaseInsensitiveString cis) &&            cis.s.equalsIgnoreCase(s); }
          這個(gè)預(yù)覽特性很值得嘗試,因?yàn)樗蜷_了通向更通用的模式匹配的大門。模式匹配的思想是為語言提供一個(gè)便捷的語法,根據(jù)特定的條件從對(duì)象中提取出組成部分。這正是instanceof操作符的用例,因?yàn)闂l件就是類型檢查,提取操作需要調(diào)用適當(dāng)?shù)姆椒ǎ蛟L問特定的字段。
          換句話說,該預(yù)覽功能僅僅是個(gè)開始,以后該功能肯定能夠減少更多的代碼冗余,從而降低bug發(fā)生的可能性。

          Record

          另一個(gè)預(yù)覽功能就是record。與前面介紹的其他預(yù)覽功能一樣,這個(gè)預(yù)覽功能也順應(yīng)了減少Java冗余代碼的趨勢(shì),能幫助開發(fā)者寫出更精準(zhǔn)的代碼。Record主要用于特定領(lǐng)域的類,它的位移功能就是存儲(chǔ)數(shù)據(jù),而沒有任何自定義的行為。
          我們開門見山,舉一個(gè)最簡(jiǎn)單的領(lǐng)域類的例子:BankTransaction,它表示一次交易,包含三個(gè)字段:日期,金額,以及描述。定義類的時(shí)候需要考慮多個(gè)方面:
          • 構(gòu)造器

          • getter方法

          • toString()

          • hashCode()和equals()

          這些部分的代碼通常由IDE自動(dòng)生成,而且會(huì)占用很大篇幅。下面是生成的完整的BankTransaction類:

          public class BankTransaction {    private final LocalDate date;    private final double amount;    private final String description;

          public BankTransaction(final LocalDate date, final double amount, final String description) { this.date = date; this.amount = amount; this.description = description; }
          public LocalDate date() { return date; }
          public double amount() { return amount; }
          public String description() { return description; }
          @Override public String toString() { return "BankTransaction{" + "date=" + date + ", amount=" + amount + ", description='" + description + '\'' + '}'; }
          @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; BankTransaction that = (BankTransaction) o; return Double.compare(that.amount, amount) == 0 && date.equals(that.date) && description.equals(that.description); }
          @Override public int hashCode() { return Objects.hash(date, amount, description); }}
          Java 14提供了一種方法可以解決這種冗余,可以更清晰地表達(dá)目的:這個(gè)類的唯一目的就是將數(shù)據(jù)整合在一起。Record會(huì)提供equals、hashCode和toString方法的實(shí)現(xiàn)。因此,BankTransaction類可以重構(gòu)如下:
          public record BankTransaction(LocalDate date,                              double amount,                              String description) {}
          通過record,可以“自動(dòng)”地得到equals,hashCode和toString的實(shí)現(xiàn),還有構(gòu)造器和getter方法。
          要想嘗試這個(gè)例子,需要用preview標(biāo)志編譯該文件:
          javac --enable-preview --release 14 BankTransaction.java
          record的字段隱含為final。因此,record的字段不能被重新賦值。但要注意的是,這并不代表整個(gè)record是不可變的,保存在字段中的對(duì)象可以是可變的。
          如果你有興趣閱讀更多關(guān)于record的內(nèi)容,可以閱讀Ben Evans最近在《Java Magazine》上發(fā)表的文章(https://blogs.oracle.com/javamagazine/records-come-to-java)。
          請(qǐng)繼續(xù)關(guān)注該功能。從培養(yǎng)新一代的Java開發(fā)者的視角來看,Record也很有意思。例如,如果你要培養(yǎng)初級(jí)開發(fā)者,那么record應(yīng)該什么時(shí)候講呢?是在講OOP之前還是之后?


          NullPointerException
          一些人認(rèn)為,拋出NullPointerException異常應(yīng)該當(dāng)做新的“Hello World”程序來看待,因?yàn)镹ullPointerException是早晚會(huì)遇到的。玩笑歸玩笑,這個(gè)異常的確會(huì)造成困擾,因?yàn)樗?jīng)常出現(xiàn)在生產(chǎn)環(huán)境的日志中,會(huì)導(dǎo)致調(diào)試非常困難,因?yàn)樗⒉粫?huì)顯示原始的代碼。例如,如下代碼:
          var name = user.getLocation().getCity().getName();
          在Java 14之前,你可能會(huì)得到如下的錯(cuò)誤:
          Exception in thread "main" java.lang.NullPointerException    at NullPointerExample.main(NullPointerExample.java:5)
          不幸的是,如果在第5行是一個(gè)包含了多個(gè)方法調(diào)用的賦值語句(如getLocation()和getCity()),那么任何一個(gè)都可能會(huì)返回null。實(shí)際上,變量user也可能是null。因此,無法判斷是誰導(dǎo)致了NullPointerException。
          在Java 14中,新的JVM特性可以顯示更詳細(xì)的診斷信息:
          Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Location.getCity()" because the return value of "User.getLocation()" is null    at NullPointerExample.main(NullPointerExample.java:5)
          該消息包含兩個(gè)明確的組成部分:
          • 后果:Location.getCity()無法被調(diào)用

          • 原因:User.getLocation()的返回值為null

          增強(qiáng)版本的診斷信息只有在使用下述標(biāo)志運(yùn)行Java時(shí)才有效:

          -XX:+ShowCodeDetailsInExceptionMessages
          下面是個(gè)例子:
          java -XX:+ShowCodeDetailsInExceptionMessages NullPointerExample
          在以后的版本中,該選項(xiàng)可能會(huì)成為默認(rèn)。
          這項(xiàng)改進(jìn)不僅對(duì)于方法調(diào)用有效,其他可能會(huì)導(dǎo)致NullPointerException的地方也有效,包括字段訪問、數(shù)組訪問、賦值等。
          總結(jié)

          Java 14提供了幾個(gè)新的預(yù)覽版語言特性和更新,能很好地幫助開發(fā)者完成日常工作。Java 14還引入了record,這是一種創(chuàng)建精確數(shù)據(jù)類的新方法。此外,NullPointerException的消息經(jīng)過了改進(jìn),能顯示明確的診斷信息。switch表達(dá)式也成了Java 14的一部分。文本塊功能可以幫你處理多行字符串,這是在引入了兩個(gè)新的轉(zhuǎn)義序列之后的另一預(yù)覽功能。還有一項(xiàng)改動(dòng)就是JDK Flight Recorder的事件流。
          可見,Java 14帶來了許多創(chuàng)新。你應(yīng)該嘗試一下這些功能,然后反饋給Java的開發(fā)團(tuán)隊(duì)。
          部分公定制的Java規(guī)范見:
          華為 Java 編程規(guī)范出爐,究竟和官方文檔有何不同?
          Google 出品 Java 編碼規(guī)范,科學(xué)又權(quán)威,強(qiáng)烈推薦!

          掃碼下面二維碼,在后臺(tái)回復(fù)關(guān)鍵字:Google規(guī)范,可獲取完整 pdf 版《Google Java編程風(fēng)格規(guī)范》。


          原文:https://blogs.oracle.com/javamagazine/java-14-arrives-with-a-host-of-new-features


          END



          前線推出學(xué)習(xí)交流群,加群一定要備注:
          研究/工作方向+地點(diǎn)+學(xué)校/公司+昵稱(如Java+上海+上交+可可)
          根據(jù)格式備注,可更快被通過且邀請(qǐng)進(jìn)群,領(lǐng)取一份專屬學(xué)習(xí)禮包


          掃碼加我微信進(jìn)群,大廠內(nèi)推和技術(shù)交流,大佬們零距離



          END


          開發(fā)者技術(shù)前線 ,匯集技術(shù)前線快訊和關(guān)注行業(yè)趨勢(shì),大廠干貨,是開發(fā)者經(jīng)歷和成長(zhǎng)的優(yōu)秀指南。
          好文點(diǎn)個(gè)在看吧!
          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91av影音先锋在线 | 操笔视频| 一般男女中文字幕 | 久久一区二区三区四区五区 | 精品国精品自拍自在线 |