Java8 之后對新開發(fā)者非常友好的特性盤點(diǎn)

在這篇文章中,我將描述自 Java8 依賴對開發(fā)者來說最重要也最友好的特性,之所以選擇 Java8 ,那是因?yàn)樗廊皇悄壳笆褂米疃嗟陌姹尽?/p>
具體可見這個(gè)調(diào)查報(bào)告:
Switch 表達(dá)式 (JDK 12)
使用 switch 表達(dá)式,你可以定義多個(gè) case 條件,并使用箭頭 -> 符號返回值,這個(gè)特性在 JDK12 之后啟用,它使得 switch 表達(dá)式更容易理解了。
public?String?newMultiSwitch(int?day)?{
???return?switch?(day)?{
??????case?1,?2,?3,?4,?5?->?"workday";
??????case?6,?7?->?"weekend";
??????default?->?"invalid";
???};
}
在 JDK12 之前,同樣的例子要復(fù)雜的多:
public?String?oldMultiSwitch(int?day)?{
???switch?(day)?{
??????case?1:
??????case?2:
??????case?3:
??????case?4:
??????case?5:
?????????return?"workday";
??????case?6:
??????case?7:
?????????return?"weekend";
??????default:
?????????return?"invalid";
???}
}
文本塊 (JDK 13)
文本塊是一個(gè)多行字符串,可以避免使用轉(zhuǎn)移字符;從 Java13 之后它成為了預(yù)覽特性,使用 """ 符號定義。接下來看看使用它聲明一個(gè) JSON 字符串有多簡單。
public?String?getNewPrettyPrintJson()?{
???return?"""
??????????{
?????????????"firstName":?"Piotr",
?????????????"lastName":?"Mińkowski"
??????????}
??????????""";
}
Java13 之前的版本:
public?String?getOldPrettyPrintJson()?{
???return?"{\n"?+
??????????"?????\"firstName\":?\"Piotr\",\n"?+
??????????"?????\"lastName\":?\"Mińkowski\"\n"?+
??????????"}";
}
新的 Optional Methods (JDK 9/ JDK 10)
Java 9/10 版本之后新增了幾種可選方法,有意思的是這兩個(gè):
orElseThrowifPresentOrElse
使用 orElseThrow 當(dāng)數(shù)據(jù)不存在時(shí)你能拋出 NoSuchElementException 異常,相反會返回?cái)?shù)據(jù)。
public?Person?getPersonById(Long?id)?{
???Optional?personOpt?=?repository.findById(id);
???return?personOpt.orElseThrow();
}
正因?yàn)槿绱?,可以避免?isPresent 中使用 if 條件。
public?Person?getPersonByIdOldWay(Long?id)?{
???Optional?personOpt?=?repository.findById(id);
???if?(personOpt.isPresent())
??????return?personOpt.get();
???else
??????throw?new?NoSuchElementException();
}
第二個(gè)有趣的方法是 ifPresentOrElse ,當(dāng)數(shù)據(jù)存在時(shí),會執(zhí)行帶數(shù)據(jù)參數(shù)的函數(shù),相反會執(zhí)行參數(shù)為空的函數(shù)。
public?void?printPersonById(Long?id)?{
???Optional?personOpt?=?repository.findById(id);
???personOpt.ifPresentOrElse(
??????System.out::println,
??????()?->?System.out.println("Person?not?found")
???);
}
在 Java8 中,你需要在 isPresent 方法中使用 if else 語句。
集合工廠方法(JDK 9)
使用 Java9 中的集合工廠方法可以簡單的使用預(yù)定義數(shù)據(jù)創(chuàng)建不可變集合。
List?fruits?=?List.of("apple",?"banana",?"orange");
Map?numbers?=?Map.of(1,?"one",?2,"two",?3,?"three");
在 Java9 之前,你可以使用 Collections ,但肯定是更復(fù)雜:
public?List?fruits()? {
???List?fruitsTmp?=?new?ArrayList<>();
???fruitsTmp.add("apple");
???fruitsTmp.add("banana");
???fruitsTmp.add("orange");
???return?Collections.unmodifiableList(fruitsTmp);
}
public?Map?numbers()? {
???Map?numbersTmp?=?new?HashMap<>();
???numbersTmp.put(1,?"one");
???numbersTmp.put(2,?"two");
???numbersTmp.put(3,?"three");
???return?Collections.unmodifiableMap(numbersTmp);
}
Records (JDK 14)
使用 Records 你可以定義一個(gè)不可變、只能訪問數(shù)據(jù)(只有 getter 方法) 的類,它可以自動(dòng)創(chuàng)建 toString,equals,hashcode 方法。
public?record?Person(String?name,?int?age)?{}
以下效果與 ?Records ?類似:
public?class?PersonOld?{
????private?final?String?name;
????private?final?int?age;
????public?PersonOld(String?name,?int?age)?{
????????this.name?=?name;
????????this.age?=?age;
????}
????public?String?getName()?{
????????return?name;
????}
????public?int?getAge()?{
????????return?age;
????}
????@Override
????public?boolean?equals(Object?o)?{
????????if?(this?==?o)?return?true;
????????if?(o?==?null?||?getClass()?!=?o.getClass())?return?false;
????????PersonOld?personOld?=?(PersonOld)?o;
????????return?age?==?personOld.age?&&?name.equals(personOld.name);
????}
????@Override
????public?int?hashCode()?{
????????return?Objects.hash(name,?age);
????}
????@Override
????public?String?toString()?{
????????return?"PersonOld{"?+
????????????????"name='"?+?name?+?'\''?+
????????????????",?age="?+?age?+
????????????????'}';
????}
}
接口中的私有方法 (JDK 9)
從 Java8 之后你就可以為接口創(chuàng)建默認(rèn)方法,但從 Java9 的私有方法你就能充分使用該特性:
public?interface?ExampleInterface?{
???private?void?printMsg(String?methodName)?{
??????System.out.println("Calling?interface");
??????System.out.println("Interface?method:?"?+?methodName);
???}
???default?void?method1()?{
??????printMsg("method1");
???}
???default?void?method2()?{
??????printMsg("method2");
???}
}
局部變量類型推導(dǎo) (JDK 10 / JDK 11)
從 Java10 之后你就能使用局部變量類型推導(dǎo)了,只需要使用 var 關(guān)鍵字來代替具體類型;在 Java11 之后你就能在 lambda 表達(dá)式中使用類型推導(dǎo)了。
public?String?sumOfString()?{
???BiFunction?func?=?(var?x,?var?y)?->?x?+?y;
???return?func.apply("abc",?"efg");
}

2021 年度報(bào)告

你可能不知道但卻很有用的 Java 特性

簡單的 for 循環(huán)也會踩的坑

用 Go 實(shí)現(xiàn)一個(gè) LRU cache

擼了一個(gè)可調(diào)試 gRPC 的 GUI 客戶端
