作者丨Sergei Dzeboev
編譯丨諾亞
Java17給Java帶來(lái)了一些變化,但也使許多開(kāi)發(fā)人員重新考慮他們遷移到其他JVM語(yǔ)言的愿望。最明顯的變化是在使Java代碼現(xiàn)代化和添加新的語(yǔ)言結(jié)構(gòu)以簡(jiǎn)化它的方向上進(jìn)行的。當(dāng)然,這個(gè)問(wèn)題并非沒(méi)有對(duì)Java核心的改變,這使得Java更加高效。
1、文本塊
文本塊功能終于出現(xiàn)在Java中。我確信這是Java程序員等待已久的變化之一?,F(xiàn)在你可以忘記難以閱讀的長(zhǎng)復(fù)合行。文本塊允許你以最方便的方式編寫(xiě)多行文本。在這樣的塊中,你可以按照自己希望的方式撰寫(xiě)文本,并且仍然可以使用轉(zhuǎn)義序列進(jìn)行更精確的格式設(shè)置。
Java11. 字符串轉(zhuǎn)義序列:
public String poem = " " +
"Twinkle, Twinkle, Little Star\n" +
" \n" +
" Twinkle, twinkle, little star,\n" +
" How I wonder what you are!\n" +
" Up above the world so high,\n" +
" Like a diamond in the sky.\n" +
" \n" +
" Twinkle, twinkle, little star,\n" +
" How I wonder what you are!";
Java17.文本塊:
public String poem = """
Twinkle, Twinkle, Little Star
Twinkle, twinkle, little star,
How I wonder what you are!
Up above the world so high,
Like a diamond in the sky.
Twinkle, twinkle, little star,
How I wonder what you are!
""";
2、Record
另一個(gè)慢慢使Java語(yǔ)言更有用的更新是record。以前,要?jiǎng)?chuàng)建一個(gè)類,我們需要描述該類,指定其字段,并添加必要的方法,例如equals、hashcode、getter和setters。自從record出現(xiàn)以來(lái),所有這些現(xiàn)在都變得不必要了。
record允許你通過(guò)僅指定必填字段來(lái)創(chuàng)建數(shù)據(jù)安全類;將自動(dòng)創(chuàng)建所有其他方法。但是,值得記住的是,record充當(dāng)數(shù)據(jù)類,創(chuàng)建是為了存儲(chǔ)數(shù)據(jù),而不是執(zhí)行各種操作。record是線程安全的,因?yàn)樗衦ecord字段都是最終的。最后要知道的重要一點(diǎn)是,用于獲取字段值的生成方法不會(huì)像經(jīng)典Java Bean 中那樣包含“get”。
Java11.數(shù)據(jù)類:
public class DataClass {
public DataClass (Integer id, String name) {
this.id = id;
this.name = name;
}
private final Integer id;
private final String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
}
Java17.Record:
public record DataClass(Integer id, String name) {
}
區(qū)別很明顯:在執(zhí)行相同功能的同時(shí),創(chuàng)建Record所需的代碼行要少得多。
3、新的switch表達(dá)式
更改列表還包括切換表達(dá)式。這些更改不僅影響了Switch表達(dá)式的語(yǔ)法(使其編寫(xiě)更加簡(jiǎn)潔),還影響了功能。Switch表達(dá)式現(xiàn)在返回迭代的結(jié)果,使編寫(xiě)代碼變得更加容易,并使其更加簡(jiǎn)潔。新的開(kāi)關(guān)表達(dá)式不再需要每個(gè)case后面都加一個(gè)break
Java11.switch表達(dá)式:
public String getSeasonDescription(Season season) {
String seasonDescription;
switch (season) {
case SPRING:
seasonDescription = "Flowers are blooming!";
break;
case SUMMER:
seasonDescription = "It's hot outside!";
break;
case AUTUMN:
seasonDescription = "Leaves are falling!";
break;
case WINTER:
seasonDescription = "Snow is coming!";
break;
default:
throw new IllegalStateException("Invalid season: " + season);
}
return seasonDescription;
}
Java 17. 增強(qiáng)的 Switch 表達(dá)式:
public String getSeasonDescription(Season season) {
return switch (season) {
case SPRING -> "Flowers are blooming!";
case SUMMER -> "It's hot outside!";
case AUTUMN -> "Leaves are falling!";
case WINTER -> "Snow is coming!";
};
}
4、instanceof模式匹配
另一項(xiàng)設(shè)計(jì)改進(jìn)也影響了操作員?,F(xiàn)在,更安全,更簡(jiǎn)潔。通過(guò)此更改,不再需要首先檢查給定對(duì)象是否是某個(gè)類的實(shí)例,然后執(zhí)行強(qiáng)制轉(zhuǎn)換;現(xiàn)在可以在一行中完成此操作。如前所述,這不僅僅是語(yǔ)法糖,而是一個(gè)更優(yōu)化的運(yùn)算符。
Java 11. 經(jīng)典的 intanceof
public void findInstance(Object o) {
if (o instanceof String) {
String s = (String) o;
System.out.printf("Object is a string %s", s);
} else if (o instanceof Number) {
Number n = (Number) o;
System.out.printf("Object is a number %n", n);
}
}
Java 17. 更新的 intanceof
public void findInstance(Object o) {
if (o instanceof String s) {
System.out.printf("Object is a string %s", s);
} else if (o instanceof Number n) {
System.out.printf("Object is a number %n", n);
}
}
5、Sealed Classes密封類
Java 17也考慮了安全性,并朝著這個(gè)方向邁出了重要的一步。這個(gè)想法是限制類或接口的繼承,同時(shí)保持其公開(kāi)。結(jié)果,新的類類型,密封類,被添加到Java中。密封類的語(yǔ)法允許你指定可以使用其功能的后代。反過(guò)來(lái),繼承者還可以允許或拒絕繼承,或者指定可以沿鏈繼承的類。此功能使你可以更靈活地創(chuàng)建項(xiàng)目,并方便地調(diào)整代碼的API。
Java 17. 密封類:
public sealed class SealedClass permits AnotherSealedClass, AnotherNonSealedClass, AnotherFinalClass {
}
Java 17. 非密封繼承人:
public non-sealed class AnotherNonSealedClass extends SealedClass {
}
Java17.最終繼承人:
public final class AnotherFinalClass extends SealedClass {
}
Java17.密封繼承人:
public sealed class AnotherSealedClass extends SealedClass permits AnotherNonSealedClassTwo {
}
Javai17.非密封繼承人二級(jí):
public non-sealed class AnotherNonSealedClassTwo extends AnotherSealedClass {
}
6、NullPointerExceptions
最后,Java 17 中一個(gè)非常有用的更新是改進(jìn)的NullPointerException!最后,在堆棧跟蹤日志中,你可以看到哪個(gè)特定字段導(dǎo)致了NullPointerException。僅此功能就應(yīng)該鼓勵(lì)你切換到Java 17。你不再需要長(zhǎng)時(shí)間在代碼中四處尋找發(fā)生異常的險(xiǎn)惡地方;現(xiàn)在Java將為你完成所有工作。
Java11.NPE:
public static void main(String... args) {
String s = null;
System.out.println(s.toLowerCase());
}
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:4)
Java17.改進(jìn)的NPE:
public static void main(String... args){
String s = null;
System.out.println(s.toLowerCase());
}
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because "s" is null
at edu.javamodules/edu.javaversions.eleventoseventeen.NpeExample.main(NpeExample.java:7)
7、其他創(chuàng)新
當(dāng)然,這并不是Java17中所做的更改的全部列表,但是討論的創(chuàng)新是最引人注目的。與往常一樣,Java開(kāi)發(fā)人員在改進(jìn)JVM方面做得非常出色,使其更加高效。
8、小結(jié)
Java17中所做的所有改進(jìn)都傳達(dá)了一個(gè)信息:是時(shí)候切換到這個(gè)版本了。過(guò)渡承諾語(yǔ)法更簡(jiǎn)潔,性能得到提高。你的項(xiàng)目將獲得安全性、靈活性和更好的錯(cuò)誤消息。如果你已經(jīng)遷移到Java11,那么遷移到Java17 會(huì)很順利。Java的競(jìng)爭(zhēng)優(yōu)勢(shì)在這里大放異彩,因?yàn)橄蚝蠹嫒菪栽试S你切換到Java17而無(wú)需更改任何代碼,并利用所有更新的功能。Java17是Java11以來(lái)又一個(gè)LTS(長(zhǎng)期支持)版本,可確保你在較長(zhǎng)時(shí)間內(nèi)收到所有必要的安全更新。
原文鏈接:https://hackernoon.com/is-migrating-from-java-11-to-java-17-worth-it