1. 程式人生 > 其它 >Java程式設計師必須知道的Java11特性

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工具類提供的新的靜態方法readStringwriteString分別進行讀寫檔案的字串內容,放在之前老麻煩了,特別是對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
來源:稀土掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。