Java程式設計師必須知道的Java11特性
Java 11是自Java 8以來的又一個LTS版本,是目前全球使用最多的LTS版本之一。今天我們接著在Java 9 到 Java 17系列文章中來認識針對普通開發者的Java 11。
字串API增強
在Java 11中,針對String
的操作進一步得到加強。避免我們在很常見的場景中引入額外的、複雜的API。
isBlank()
用來判斷字串是不是空字元""
或者trim()
之後(" "
)為空字元:
String blankStr = " ";
// true
boolean trueVal = blankStr.isBlank();
複製程式碼
lines()
將一個字串按照行終止符(換行符\n
\r
)進行分割,並將分割為Stream
流:
String newStr = "Hello Java 11 \n felord.cn \r 2021-09-28";
Stream<String> lines = newStr.lines();
lines.forEach(System.out::println);
// Hello Java 11
// felord.cn
// 2021-09-28
複製程式碼
strip()
去除字串前後的“全形和半形”空白字元:
String str = "HELLO\u3000";
// str = 6
System.out.println("str = " + str.length());
// trim = 6
System.out.println("trim = " + str.trim().length());
// strip = 5
System.out.println("strip = " + str.strip().length());
複製程式碼
這不由得想起來trim()
方法,從上面也看出來了差別,trim()
只能去除半形
空白符。
strip()
方法還有兩個變種,stripLeading()
用來去除前面的全形半形空白符;stripTrailing()
用來去除尾部的全形半形空白符。
repeat(n)
按照給定的次數重複串聯字串的內容:
String str = "HELLO";
// 空字元
String empty = str.repeat(0);
// HELLO
String repeatOne = str.repeat(1);
// HELLOHELLO
String repeatTwo = str.repeat(2);
複製程式碼
集合轉對應型別的陣列
之前想集合轉對應的陣列很麻煩,要麼用迭代;要麼用Stream
流,現在你可以這樣:
List<String> sampleList = Arrays.asList("felord.cn", "java 11");
// array = {"felord.cn", "java 11"};
String[] array = sampleList.toArray(String[]::new);
複製程式碼
斷言取反
java.util.function.Predicate<T>
是我們很常用的斷言謂詞函式。在以前取反我們得藉助於!
符號,到了Java 11我們可以藉助於其靜態方法not
來實現,這樣語義就更加清晰了:
List<String> sampleList = Arrays.asList("felord.cn", "java 11","jack");
// [jack]
List<String> result = sampleList.stream()
// 過濾以j開頭的字串
.filter(s -> s.startsWith("j"))
// 同時不包含11的字串
.filter(Predicate.not(s -> s.contains("11")))
.collect(Collectors.toList());
複製程式碼
其實Predicate<T>
在最初版本還提供了一個取反的預設方法:
default Predicate<T> negate() {
return (t) -> !test(t);
}
複製程式碼
這個我在往期文章中也使用過它來做組合校驗,這兩個方法的場景是不一樣的。
var可以用於修飾Lambda區域性變數
在Java 10中引入的var
來進行型別推斷。在Java 10中它不能用於修飾Lambda表示式的入參,其實對於一個Lambda表示式來說它入參的型別其實是可以根據上下文推斷出來的。拿上面的例子來說,s -> s.startsWith("j")
中的s
肯定是字串型別,因此在Java 11中var
可以用於修飾Lambda區域性變數:
List<String> result = sampleList.stream()
// 過濾以j開頭的字串
.filter((@NotNull var s) -> s.startsWith("j"))
// 同時不包含11的字串
.filter(Predicate.not((@NotNull var s) -> s.contains("11")))
.collect(Collectors.toList());
複製程式碼
如果我們不宣告
var
就沒有辦法為輸入引數新增@NotNull
註解。
檔案中讀寫字串內容更方便
Java 11中可以更輕鬆地從檔案中讀取和寫入字串內容了,我們可以通過Files
工具類提供的新的靜態方法readString
和writeString
分別進行讀寫檔案的字串內容,放在之前老麻煩了,特別是對IO流不熟悉的同學來說。java培訓現在簡單幾行就搞定了:
String dir= "C://yourDir";
// 寫入檔案
Path path = Files.writeString(Files.createTempFile(dir, "hello", ".txt"), "hello java 11");
// 讀取檔案
String fileContent = Files.readString(path);
複製程式碼
巢狀類的訪問控制規則
在Java 11之前,內部巢狀類訪問外部類的私有屬性和方法是可行的:
public class Outer {
private int outerInt;
class Inner {
public void printOuterField() {
System.out.println("Outer field = " + outerInt);
}
}
}
複製程式碼
但是如果你通過反射API實現內部類訪問外部類的私有屬性和方法就會丟擲IllegalStateException
異常。Java 11 修復了反射不能訪問的問題.
JVM 訪問規則不允許巢狀類之間進行私有訪問。我們能通過常規方式可以訪問是因為 JVM 在編譯時為我們隱式地建立了橋接方法。Java 11 中引入了兩個新的屬性:一個叫做
NestMembers
的屬性,用於標識其它已知的靜態 nest 成員;另外一個是每個 nest 成員都包含的NestHost
屬性,用於標識出它的 nest 宿主類。在編譯期就映射了雙方的寄宿關係,不再需要橋接了。
HttpClient支援HTTP2
HttpClient
到了Java 11後開始支援HTTP2,底層進行了大幅度的優化,並且現在完全支援非同步非阻塞。
HttpClient
的包名由jdk.incubator.http
改為java.net.http
。
其它
Java 11 中,還有一些其它方面的特性和優化,比如引入了ZGC,支援支援 TLS 1.3 協議,引入了動態呼叫(invokedynamic)機制,另外原來商業版的JFR也進行了開源整合等等。在年初的Java生態調查資料顯示Java 11的使用者數量大幅增長,成為了主流版本選擇之一。
作者:碼農小胖哥
連結:https://juejin.cn/post/7023219454095917086
來源:稀土掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。