您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Java14有哪些新特性”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Java14有哪些新特性”吧!
1、Switch表達(dá)式
Java 14中的switch表達(dá)式將會永久存在。
在之前的發(fā)布中,switch表達(dá)式只是一個“預(yù)覽”階段的特性。我想提醒一下,“預(yù)覽”階段的特性的目的是為了收集反饋,這些特性可能會隨時改變,根據(jù)反饋結(jié)果,這些特性甚至可能會被移除,但通常所有預(yù)覽特性最后都會在Java中固定下來。
新的switch表達(dá)式的優(yōu)點是,不再有缺省跳過行為(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; } };
2、文本塊
Java 13引入的一個預(yù)覽功能是文本塊。有了文本塊,多行的字符串字面量就很容易編寫了。這個功能在Java 14中進(jìn)行第二次預(yù)覽,而且發(fā)生了一些變化。例如,多行文本的格式化可能需要編寫許多字符串連接操作和轉(zhuǎn)義序列。下面的代碼演示了一個HTML的例子:
String html = "<HTML>" + "\n\t" + "<BODY>" + "\n\t\t" + "<H1>\"Java 14 is here!\"</H1>" + "\n\t" + "</BODY>" + "\n" + "</HTML>";
有了文本塊,就可以簡化這一過程,只需使用三引號作為文本塊的起始和結(jié)束標(biāo)記,就能編寫出更優(yōu)雅的代碼:
String html = """ <HTML> <BODY> <H1>"Java 14 is here!"</H1> </BODY> </HTML>""";
與普通的字符串字面量相比,文本塊的表達(dá)性更好。
Java 14引入了兩個新的轉(zhuǎn)義序列。第一,可以使用新的 \s 轉(zhuǎn)義序列來表示一個空格。第二,可以使用反斜杠 \ 來避免在行尾插入換行字符。這樣可以很容易地在文本塊中將一個很長的行分解成多行來增加可讀性。
例如,現(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.\ """;
3、instanceof的模式匹配
Java 14引入了一個預(yù)覽特性,有了它就不再需要編寫先通過instanceof判斷再強制轉(zhuǎn)換的代碼了。例如,下面的代碼:
if (obj instanceof Group) { Group group = (Group) obj; // use group specific methods var entries = group.getEntries(); }
利用這個預(yù)覽特性可以重構(gòu)為:
if (obj instanceof Group group) { var entries = group.getEntries(); }
由于條件檢查要求obj為Group類型,為什么還要像第一段代碼那樣在條件代碼塊中指明obj為Group類型呢?這可能會引發(fā)錯誤。
這種更簡潔的語法可以去掉Java程序里的大多數(shù)強制類型轉(zhuǎn)換。
JEP 305解釋了這項改變,并給出了Joshuoa Bloch的著作《Effective Java》中的一個例子,演示了下面兩種等價的寫法:
@Override public boolean equals(Object o) { return (o instanceof CaseInsensitiveString) && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); }
這段代碼嗎中冗余的CaseInsensitiveString強制類型轉(zhuǎn)換可以去掉,轉(zhuǎn)換成下面的方式:
@Override public boolean equals(Object o) { return (o instanceof CaseInsensitiveString cis) && cis.s.equalsIgnoreCase(s); }
這個預(yù)覽特性很值得嘗試,因為它打開了通向更通用的模式匹配的大門。模式匹配的思想是為語言提供一個便捷的語法,根據(jù)特定的條件從對象中提取出組成部分。這正是instanceof操作符的用例,因為條件就是類型檢查,提取操作需要調(diào)用適當(dāng)?shù)姆椒?,或訪問特定的字段。
換句話說,該預(yù)覽功能僅僅是個開始,以后該功能肯定能夠減少更多的代碼冗余,從而降低bug發(fā)生的可能性。
4、Record
另一個預(yù)覽功能就是record。與前面介紹的其他預(yù)覽功能一樣,這個預(yù)覽功能也順應(yīng)了減少Java冗余代碼的趨勢,能幫助開發(fā)者寫出更精準(zhǔn)的代碼。Record主要用于特定領(lǐng)域的類,它的位移功能就是存儲數(shù)據(jù),而沒有任何自定義的行為。
我們開門見山,舉一個最簡單的領(lǐng)域類的例子:BankTransaction,它表示一次交易,包含三個字段:日期,金額,以及描述。定義類的時候需要考慮多個方面:
構(gòu)造器
getter方法
toString()
hashCode()和equals()
這些部分的代碼通常由IDE自動生成,而且會占用很大篇幅。下面是生成的完整的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á)目的:這個類的唯一目的就是將數(shù)據(jù)整合在一起。Record會提供equals、hashCode和toString方法的實現(xiàn)。因此,BankTransaction類可以重構(gòu)如下:
public record BankTransaction(LocalDate date, double amount, String description) {}
通過record,可以“自動”地得到equals,hashCode和toString的實現(xiàn),還有構(gòu)造器和getter方法。
要想嘗試這個例子,需要用preview標(biāo)志編譯該文件:
javac --enable-preview --release 14 BankTransaction.java
record的字段隱含為final。因此,record的字段不能被重新賦值。但要注意的是,這并不代表整個record是不可變的,保存在字段中的對象可以是可變的。
5、NullPointerException
一些人認(rèn)為,拋出NullPointerException異常應(yīng)該當(dāng)做新的“Hello World”程序來看待,因為NullPointerException是早晚會遇到的。玩笑歸玩笑,這個異常的確會造成困擾,因為它經(jīng)常出現(xiàn)在生產(chǎn)環(huán)境的日志中,會導(dǎo)致調(diào)試非常困難,因為它并不會顯示原始的代碼。例如,如下代碼:
var name = user.getLocation().getCity().getName();
在Java 14之前,你可能會得到如下的錯誤:
Exception in thread "main" java.lang.NullPointerException at NullPointerExample.main(NullPointerExample.java:5)
不幸的是,如果在第5行是一個包含了多個方法調(diào)用的賦值語句(如getLocation()和getCity()),那么任何一個都可能會返回null。實際上,變量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)
該消息包含兩個明確的組成部分:
后果:Location.getCity()無法被調(diào)用
原因:User.getLocation()的返回值為null
增強版本的診斷信息只有在使用下述標(biāo)志運行Java時才有效:
-XX:+ShowCodeDetailsInExceptionMessages
下面是個例子:
java -XX:+ShowCodeDetailsInExceptionMessages NullPointerExample
在以后的版本中,該選項可能會成為默認(rèn)。
這項改進(jìn)不僅對于方法調(diào)用有效,其他可能會導(dǎo)致NullPointerException的地方也有效,包括字段訪問、數(shù)組訪問、賦值等。
到此,相信大家對“Java14有哪些新特性”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。