Java 8 + 10 = Java 18

碼農小胖哥發表於2022-03-22

明天Java 18將正式釋出, 雖然它不是長期支援 (LTS) 版本,但它卻實現了九個 JEP(在Java 18列出)。有哪些特性值得關注呢?今天胖哥為你提前解讀。再看、點贊、轉發、關注來一波吧。

JEP 400

將 UTF-8 指定為標準 Java API 的預設字符集。通過此更改,依賴於預設字符集的 API 將在所有實現、作業系統、語言環境和配置中保持一致。

JEP 408

Java內部終於有原生的Web伺服器了。但是請注意它沒有可用的 CGI 或類似 Servlet 的功能。該工具可用於原型設計、臨時編碼和測試目的,尤其是在教育環境中。

它並不是JettyApache Tomcat等產品的競品,也無法而且不推薦在生產環境中使用。僅僅是提供一個命令列工具來輔助幫助開發人員設計、測試、教學。

JEP 413

支援在Java API文件中使用程式碼片段。以前在Java程式碼的註釋中如果要寫一些樣例非常麻煩,甚至還要進行字元轉義。現在Java註釋引入了一個新的標記 @snippet 來解決註釋中包含程式碼片段樣例的問題。

它可以內聯使用:

/**
 * The following code shows how to use {@code Optional.isPresent}:
 * {@snippet :
 * if (v.isPresent()) {
 *     System.out.println("v: " + v.get());
 * }
 * }
 */

也可以引用外部片段:

/**
 * The following code shows how to use {@code Optional.isPresent}:
 * {@snippet file="ShowOptional.java" region="example"}
 */

ShowOptional.java就是它引用的原始碼:

public class ShowOptional {
    void show(Optional<String> v) {
        // @start region="example"
        if (v.isPresent()) {
            System.out.println("v: " + v.get());
        }
        // @end
    }
}

JEP 417

引入一個 API 來表達向量計算,該計算可以在執行時可靠地編譯為支援的 CPU 架構上的最佳向量指令,從而實現優於等效標量計算的效能。 目前是第三次孵化。

JEP 418

為主機名和地址解析定義服務提供者介面 (SPI),以便java.net.InetAddress可以使用平臺內建解析器以外的解析器。 這個對於網際網路一些協議的接入提供了入口,同時你也可以對現有方案進行一些改進和定製。

JEP 419

Foreign Function & Memory API ( JEP 419 ) 是此版本中實現的更重要的 JEP 之一,因為它是Project Panama中包含的孵化元件之一。 Panama 正在簡化將 Java 程式連線到非 Java 元件的過程。這一特殊功能在其第二次孵化迭代中引入了一個 APIJava 程式通過該 API 呼叫Native類庫並處理Native資料。目的是取代設計的非常不理想的Java Native Interface (JNI)

大家都知道其它語言有非常棒的一些類庫,但是Java想呼叫其它語言的類庫目前需要使用JNI。但是JNI被設計得太複雜了,讓很多Java開發者難以上手。如果這一狀況得到改變,那麼利用Java去呼叫一些C或者C++音視訊處理庫和Python的機器學習庫將是非常容易的事情。

JEP 420

實現的唯一真正影響 Java 語言的 JEP 是Pattern Matching for switch ( JEP 420 ),它在 Java 17 中首次預覽(這是第二次預覽)。其目的是“通過對switch 表示式和語句的模式匹配以及對模式語言的擴充套件來增強 Java 程式語言 。在 Java 16 中,JEP 394擴充套件了instanceof運算子以採用型別模式並執行模式匹配

// Old code
if (o instanceof String) {
    String s = (String)o;
    ... use s ...
}

// New code
if (o instanceof String s) {
    ... use s ...
}

我們使用instanceof後無需再對物件進行型別轉換就可以使用其真實的型別。

Java 14又引入了switch表示式:

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
    default                     -> 11;    
};

如果這兩個能結合起來,switch能進行模式匹配的話,下面的句子將大大簡化:

static String formatter(Object o) {
    String formatted = "unknown";
    if (o instanceof Integer i) {
        formatted = String.format("int %d", i);
    } else if (o instanceof Long l) {
        formatted = String.format("long %d", l);
    } else if (o instanceof Double d) {
        formatted = String.format("double %f", d);
    } else if (o instanceof String s) {
        formatted = String.format("String %s", s);
    }
    return formatted;
}

JEP 420的預覽特性,將會把上面冗長的程式碼簡化為:

static String formatterPatternSwitch(Object o) {
    return switch (o) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        default        -> o.toString();
    };
}

是不是更加清晰了呢?

JEP 421

Object物件有一個 finalize 方法,該方法用於例項被垃圾回收器回收的時觸發的操作。當 GC (垃圾回收器) 確定不存在對該物件的有更多引用時,物件的垃圾回收器就會呼叫這個方法。當時它的設計用來避免記憶體洩露,現在已經有了更好的替代方案try-with-resourcesJava 9引入的 java.lang.ref.Cleaner

因此,所有該方法會被標記為過時,未來將被移除。

總結

很少有人在生產中使用 JDK 18,因為它不是 LTS 版本。去年九月釋出JDK 17 LTS 版本更為重要,很多類庫,特別是Spring framework 6.0Spring Boot 3.0 都將基於JDK17,你還要在Java 8堅持多久呢?已經相差了10個版本了。下一個是LTS是 2023 年 9 月的 Java 21

關注公眾號:Felordcn 獲取更多資訊

個人部落格:https://felord.cn

相關文章