➜ Old React website
Chung Cheuk Hang MichaelJava Web Developer
React JS 網頁開發筆記(一)在 Java 項目中使用 Lombok

Java 8 之後既新功能

Continued from previous post:
Java 開發筆記(三)

Table of contents

1 Java 9 帶黎既改變

1.1 模組化 - Java Platform Module System (JPMS)

Java 9 提供左 module system,呢個功能亦叫做 Project Jigsaw。
模組化功能主要係想解決:
  • JAR 檔定義喺類別路徑中既順序,經常會有同名類別遮蓋既問題
  • JAR 對包裝既類別沒有封裝機制,即使開發中既程式庫想隱藏底層使用到既實作品,但只要係 public 既類型,API 開發者就見得到、用得到
  • JAR 檔案充其量只係個方便傳送既器皿,佢冇辦法表示彼此之間既依賴關係,當發生 ClassNotFoundException 既時候,我地好難知道到底缺少左邊個 JAR 檔
  • JDK 1.1 由 10MB 以下到而家 JDK 8+ 既 200+ MB,越黎越大,模組化亦可以令到需要既 JRE 細啲
參考資料:

1.2 interface 支援 private methods

Java 9 既 interface 既 methods 可以有 private access modifier,令到 interface 更加似 class。
呢啲 private methods 唔可以係 abstract
1public interface Foo { 2 3 private void sayHi() { 4 // do sth 5 } 6}

1.3 Anonymous class 可以用 <>

<> 又叫 diamond operator,係用黎表示 generic type(s) 重複。
Java 9 之前,anonymous class 要我地寫清楚 generic type(s) 或重複前面定義變數既 generic type(s),但 Java 9 既 anonymous class 就唔需要再重複 <> 裡面既 generic type(s),留空就可以。

1.4 Try-with-resources 支援 try 前定義既變數

只要變數係 final 或 effectively final,就可以用喺 try block。
Java 9 之前既 try-with-resources:
try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { // ... }
Java 9 既 try-with-resources:
1final Scanner scanner = new Scanner(new File("testRead.txt")); 2PrintWriter writer = new PrintWriter(new File("testWrite.txt")); 3 4try (scanner; writer) { 5 // ... 6}

1.5 Collections API 新增 of 既 method

就好似 Arrays.asList 咁,Java 9 既 collection classes 新增左 of static method:
List<Integer> myList = List.of(1, 2, 3); Set<Integer> mySet = Set.of(1, 2, 3); Map<String, Integer> myMap = Map.of("one", 1, "two", 2);
以上既 of methods 都會返回一個 immutable 既 collection object。

1.6 Reactive streams publisher/subscriber framework

Java 9 新增左 reactive streams publish-subscribe framework for asynchronous stream processing with non-blocking backpressure(支援異步非阻塞背壓流式處理既反應式流發布/訂閱框架)。
參考資料:

1.7 Stream 新增 methods

Java 9 既 Stream 新增左以下 methods:
  • dropWhile
  • takeWhile
  • ofnullable
  • iterate​(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)

1.8 Arrays 新增 mismatch method

Java 9 既 Arrays 新增左 mismatch static method,可以搵出兩個 arrays 既第一個唔同既元素。

1.9 StackWalker API

Java 9 新增既 StackWalker API 可以畀我地遊歷、流處理 method call 既整個 stack。
參考資料:

1.10 Process API 改良

Java 9 改良左 Process API 既 ProcessHandle,而家我地可以攞到:
  • Process ID(PID)
  • User
  • 開始時間
  • 用左幾多 CPU 時間
  • 幾多個本地 processes 運行緊

2 Java 10 帶黎既改變

2.1 新增 var keyword

Java 10 新增左 var keyword 用於簡化定義 local 變數。Java compiler 會根據 value 去推斷變量既 type。
var greeting = "Hello World!";

3 Java 11 帶黎既改變

3.1 String 新增 methods

  • isBlank
  • lines
  • repeat
  • strip

3.2 HttpClient API 支援 HTTP/2

Java 11 之前,HttpClient 只係支援 HTTP/1.1,Java 11 既 HttpClient 就支援 HTTP/1.1 同 HTTP/2(默認)。

3.3 移除 Java EE

Java 11 移除左 Java EE––包括 JAX-WS、JAXB、JSR-250 既 annotations(如 @PostConstruct@PreDestroy 等),但我地仲可以透過加入如 javax.annotationjavax.annotation-api 等 Maven dependencies 黎重新取得相關 Java EE 功能。

3.4 移除 JavaFX

為左更好咁發展 JavaFX,Oracle 認為應該將 JavaFX 獨立出黎,所以 Java 11 移除左 JavaFX,以後想以最新既 Java graphical user interface(GUI)rich client 技術開發 desktop apps 就要自行將 OpenJFX 既 JavaFX 加入 project 既 classpath。
參考資料:

4 Java 12 帶黎既改變

4.1 Collectors 新增 teeing method

Java 12 既 Collectors 新增左 teeing 既 method,可以將兩個 Collector 既結果合併,放落一個 object 裡面,例如 Map
參考資料:

4.2 Files 新增 mismatch method

Java 12 既 Files 新增左 mismatch static method,可以比較兩個 Path 既檔案內容,並且搵出第一個唔同既 byte。

5 Java 13 帶黎既改變

5.1 重寫 Socket API

Java 13 將好舊既 Socket API 底層 Java + C code 重寫左。

6 Java 14 帶黎既改變

6.1 switch 語句改良

Java 14 既 switch 語句可以直接返回一樣野。
1int numLetters = switch (day) { 2 case MONDAY, FRIDAY, SUNDAY -> 6; 3 case TUESDAY -> 7; 4 default -> { 5 String s = day.toString(); 6 int result = s.length(); 7 yield result; 8 } 9};

7 Java 15 帶黎既改變

7.1 Text block(文本塊)、String 新增 formatted method

Java 15 畀我地將多行既 string 直接放喺 source code 度,唔需要用 newline(\n)甚或自己分開幾行然後用 + 號。
1String html = """ 2<html> 3 <body> 4 <p>Hello, world</p> 5 </body> 6</html> 7""";
Java compiler 會根據咁多行而搵出最大既共同縮排距離,然後將全部行移除相同既縮排距離。如果唔想出到黎既 string 有縮排,但又想寫出黎既 code 有縮排,formatting 好睇一啲,可以將最後一行加多啲空格增加縮排距離。
Java 15 既 String 亦新增左 formatted 既 instance method,作用同 Stringformat static method 無異。
參考資料:

7.2 詳細既 NullPointerException error message

Java 15 既 NullPointerException 帶黎既 error message 會提供詳細既資訊畀我地知道邊個變數 null 左。
Exception in thread "main" java.lang.NullPointerException: Cannot read field "c" because "a.b" is null

7.3 移除 Nashorn JavaScript engine

Java 15 移除左 Nashorn JavaScript engine。

8 Java 16 帶黎既改變

8.1 record type

Java 16 既 record type 可以實現 Lombok 既部分功能,減少寫 boilerplate code。
record Point(int x, int y) { }
伴隨呢個新功能,Java 16 亦都改變左 non-static inner class 既一啲規則,而家我地係可以 declare static fields 以及 static methods。
Java 16 之前(將 MyInnerClass 改成 static 先 compile 到):
1public class MyOuterClass { 2 3 // 注意:non-static inner class 4 public class MyInnerClass { 5 6 // JDK 16 之前既版本會有 compilation error: 7 // The field myField cannot be declared static in a non-static inner type, 8 // unless initialized with a constant expression 9 static String myField = "foo"; 10 11 // JDK 16 之前既版本會有 compilation error: 12 // The method myMethod cannot be declared static; 13 // static methods can only be declared in a static or top level type 14 static String myMethod() { 15 return "foo"; 16 } 17 } 18 19 public static void main(String[] args) { 20 System.out.println(MyInnerClass.myField); 21 System.out.println(MyInnerClass.myMethod()); 22 } 23}

8.2 instanceof 既 pattern matching

Java 16 既 instanceof 可以直接 cast 成某個 type 再拎黎用。
if (obj instanceof String str) { String value = str; }

8.3 Stream 新增 mapMulti method

寫法一:
1final List<String> result = input.stream().mapMulti((Object element, Consumer<String> consumer) -> { 2 consumer.accept(element + "-1"); 3 consumer.accept(element + "-2"); 4}).collect(toList()); 5 6System.out.println(result); // [a-1, a-2, b-1, b-2, c-1, c-2]
寫法二:
1final List<String> result2 = input.stream().<String>mapMulti((element, consumer) -> { 2 consumer.accept(element + "-1"); 3 consumer.accept(element + "-2"); 4}).collect(toList()); 5 6System.out.println(result2); // [a-1, a-2, b-1, b-2, c-1, c-2]
參考:

9 Java 17 帶黎既改變

9.1 新增 sealed modifier、permits keyword

Java 17 新增左 sealed type-level modifier 及 permits keyword,只有 permits 後面既 type(s) 先可以 extends 或者 implements 呢個 class 或者 interface,畀我地更好咁控制 inheritance。Java 17 之前只有加上 final 或者唔加 final 既選擇,冇辦法揀某啲 subtype(s) 黎開放 inheritance。
permits 後面既 type(s) 必須要有 finalsealednon-sealed 既 modifier。
例子:
Shape.java
public sealed class Shape permits Circle, Square, Rectangle { // ... }
Circle.java
public final class Circle extends Shape { // ... }
Square.java
public non-sealed class Square extends Shape { // ... }
Rectangle.java
public sealed class Rectangle extends Shape permits FilledRectangle { // ... }
FilledRectangle.java
public final class FilledRectangle extends Rectangle { // ... }
如果 subclass 或者 subinterface 係喺同一個 Java class file 裡面定義,就可以唔洗打 permits,自動賦予 inheritance 權利畀呢啲 subclass 或者 subinterface。
參考資料:

10 【預覽功能】

預覽既功能已經喺 JDK 裡面,只要啟動某啲配置就可以用到,只係未被定為最終完成版,之後可能仲會有改動,應該會喺後續既新版推出。

10.1 Vector API

Java 16(預覽)新增左 Vector API,其作用係使用 CPU 既 SIMD(Single Instruction Multiple Data)指令黎提升 CPU 處理 int、float、long、double、short、byte 既 array 既運算效率,有別於現時既 for loop 對每一個 array element 逐一單獨處理。
參考資料:

10.2 switch 既 pattern matching

1switch (o) { 2 case null -> System.out.println("null"); 3 case String s -> System.out.println("String"); 4 case int[] arr -> System.out.println("Array length" + arr.length); 5 case MyClass obj -> System.out.println(obj.toString()); 6 default -> System.out.println("Something else"); 7}

10.3 Virtual threads

參考:

11 參考資料