2024年威哥攜三位兄弟,Mask、強(qiáng)哥、索尓一起探索Java?JDK21 LTS版,JDK 21 帶來了一些令人興奮的新特性和改進(jìn),總結(jié)了一些自己的筆記,分享給大家,本文將介紹其中一些重要的內(nèi)容,并提供相應(yīng)的示例代碼以幫助讀者更好地理解,閱讀全文需要花費(fèi)你10分鐘,收藏起來肯定有需要用的時(shí)候。
JDK 21 引入了 JEP 400,它為 Java 程序集提供了一種新的模塊化方式。這項(xiàng)功能使得開發(fā)者能夠更輕松地組織和管理大型項(xiàng)目中的代碼。它通過?java.assembly
?模塊提供支持。
示例代碼:
import java.assembly.*;
assembly HelloWorld {
module com.example.helloworld {
requires java.base;
exports com.example.helloworld;
}
}
解釋:上面的示例代碼展示了如何使用?java.assembly
?模塊來定義一個(gè)簡單的 Java 程序集。你可以通過?requires?來指定依賴關(guān)系,并通過?exports?來導(dǎo)出你的模塊。
Java 17 引入了模式匹配,JDK 21 在此基礎(chǔ)上進(jìn)一步改進(jìn)了對(duì)?instanceof?的模式匹配支持?,F(xiàn)在,可以直接在?instanceof?表達(dá)式中使用類型轉(zhuǎn)換。
示例代碼:
class Example {
void process(Object obj) {
if (obj instanceof String s) {
System.out.println("String length: " + s.length());
} else {
System.out.println("Not a String");
}
}
}
解釋:上面的示例代碼展示了如何使用改進(jìn)后的?instanceof,其中?s?是在匹配成功后直接轉(zhuǎn)換為?String?類型,從而可以直接使用它的方法。
JDK 21 對(duì)隨機(jī)生成器進(jìn)行了改進(jìn),引入了一些新的方法和算法,提高了其性能和質(zhì)量。
示例代碼:
import java.util.Random;
public class Example {
public static void main(String[] args) {
Random random = new Random();
int randomNumber = random.nextInt(100);
System.out.println("Random number: " + randomNumber);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中改進(jìn)的?Random?類來生成一個(gè)介于 0 和 100 之間的隨機(jī)數(shù)。
JDK 21 引入了 JEP 413,這項(xiàng)功能提供了一種非侵入式的方式來進(jìn)行 Java 日志記錄,使得開發(fā)者能夠更輕松地管理應(yīng)用程序的日志信息。
示例代碼:
import java.logging.Logger;
public class Example {
private static final Logger logger = Logger.getLogger(Example.class.getName());
public static void main(String[] args) {
logger.info("This is an informational message.");
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的?
java.logging.Logger
?類來記錄日志信息,而無需引入額外的日志框架。
JDK 11 引入了原生的 HTTP 客戶端,JDK 21 在此基礎(chǔ)上進(jìn)一步增強(qiáng)了對(duì) HTTP/2 的支持,使得開發(fā)者能夠更高效地與支持 HTTP/2 協(xié)議的服務(wù)器進(jìn)行通信。
示例代碼:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Response code: " + response.statusCode());
System.out.println("Response body: " + response.body());
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中增強(qiáng)的原生 HTTP 客戶端與支持 HTTP/2 協(xié)議的服務(wù)器進(jìn)行通信。
JDK 21 引入了 JEP 419,該功能提供了一組改進(jìn)的本地字符串操作方法,使得開發(fā)者能夠更輕松地處理字符串操作。
示例代碼:
import java.nio.charset.StandardCharsets;
public class Example {
public static void main(String[] args) {
String str = "Hello, 世界!";
// 計(jì)算字符串長度(代碼點(diǎn)數(shù)量)
int codePointCount = str.codePointCount(0, str.length());
System.out.println("Code point count: " + codePointCount);
// 將字符串轉(zhuǎn)換為字節(jié)數(shù)組
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
System.out.println("Byte length: " + bytes.length);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的改進(jìn)的字符串操作方法,包括計(jì)算代碼點(diǎn)數(shù)量和將字符串轉(zhuǎn)換為字節(jié)數(shù)組等。
JDK 21 引入了 JEP 422,該功能提供了一些改進(jìn)的異常處理機(jī)制,使得開發(fā)者能夠更清晰地管理和處理異常情況。
示例代碼:
public class Example {
public static void main(String[] args) {
try {
// 可能會(huì)拋出異常的代碼
int result = divide(10, 0);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
// 捕獲并處理異常
System.err.println("Error: " + e.getMessage());
}
}
private static int divide(int dividend, int divisor) {
if (divisor == 0) {
throw new ArithmeticException("Division by zero");
}
return dividend / divisor;
}
}
解釋:上面的示例代碼展示了如何使用改進(jìn)的異常處理機(jī)制來捕獲和處理可能發(fā)生的異常情況。
JDK 21 引入了 JEP 425,該功能提供了一些增強(qiáng)的數(shù)組支持,包括更靈活的數(shù)組操作和更豐富的數(shù)組功能。
示例代碼:
public class Example {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5};
// 使用流操作對(duì)數(shù)組進(jìn)行處理
int sum = Arrays.stream(array).sum();
System.out.println("Sum: " + sum);
// 使用 Arrays 類的方法進(jìn)行數(shù)組排序
Arrays.sort(array);
System.out.println("Sorted array: " + Arrays.toString(array));
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中增強(qiáng)的數(shù)組支持功能,包括使用流操作對(duì)數(shù)組進(jìn)行處理以及使用 Arrays 類的方法對(duì)數(shù)組進(jìn)行排序。
JDK 21 引入了 JEP 428,該功能為沒有明確指定序列化版本 UID 的類提供了一個(gè)默認(rèn)的序列化版本 UID,從而增強(qiáng)了序列化的兼容性。
示例代碼:
import java.io.*;
public class Example implements Serializable {
private static final long serialVersionUID = -8041599049250916662L;
private String name;
private int age;
public Example(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) throws Exception {
Example obj = new Example("John", 30);
// 將對(duì)象序列化到文件
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("example.ser"));
out.writeObject(obj);
out.close();
// 從文件中讀取對(duì)象并反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("example.ser"));
Example newObj = (Example) in.readObject();
in.close();
System.out.println("Deserialized object: " + newObj);
}
@Override
public String toString() {
return "Example{name='" + name + "', age=" + age + '}';
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中默認(rèn)的序列化版本 UID 來提高序列化的兼容性,使得即使沒有明確指定序列化版本 UID 的類也能夠正確地進(jìn)行序列化和反序列化操作。
JDK 21 引入了 JEP 430,該功能提供了一些增強(qiáng)的實(shí)例操作,使得開發(fā)者能夠更輕松地對(duì)實(shí)例進(jìn)行操作和管理。
示例代碼:
import java.util.Optional;
public class Example {
public static void main(String[] args) {
String str = "Hello, world!";
// 使用 Optional 類的靜態(tài)方法創(chuàng)建可空對(duì)象
Optional<String> optionalStr = Optional.ofNullable(str);
// 如果值存在,則對(duì)其進(jìn)行操作
optionalStr.ifPresent(s -> System.out.println("Length: " + s.length()));
// 如果值為空,則提供默認(rèn)值
String defaultValue = optionalStr.orElse("Default value");
System.out.println("Value: " + defaultValue);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中增強(qiáng)的實(shí)例操作功能,包括使用 Optional 類來對(duì)實(shí)例進(jìn)行操作和管理。
JDK 21 引入了 JEP 432,該功能提供了一種并發(fā)安全的隨機(jī)數(shù)生成器,使得開發(fā)者能夠更安全地在多線程環(huán)境中生成隨機(jī)數(shù)。
示例代碼:
import java.util.concurrent.ThreadLocalRandom;
public class Example {
public static void main(String[] args) {
// 生成一個(gè)介于 0 和 100 之間的隨機(jī)數(shù)
int randomNumber = ThreadLocalRandom.current().nextInt(0, 101);
System.out.println("Random number: " + randomNumber);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中并發(fā)安全的隨機(jī)數(shù)生成器來生成隨機(jī)數(shù),而無需擔(dān)心多線程環(huán)境下的競態(tài)條件。
JDK 21 引入了 JEP 434,該功能增強(qiáng)了本地類型推斷,使得開發(fā)者能夠更輕松地在各種情況下使用 var 關(guān)鍵字進(jìn)行類型推斷。
示例代碼:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Example {
public static void main(String[] args) {
// 增強(qiáng)的本地類型推斷
var list = new ArrayList<String>();
list.add("Java");
list.add("Python");
// 遍歷集合
for (var item : list) {
System.out.println(item.toUpperCase());
}
// 使用 var 推斷 Map 中的鍵值對(duì)類型
var map = Map.of("a", 1, "b", 2, "c", 3);
map.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中增強(qiáng)的本地類型推斷功能,在不損失可讀性的情況下更靈活地使用 var 關(guān)鍵字進(jìn)行類型推斷。
JDK 21 引入了 JEP 440,該功能增強(qiáng)了 Java 平臺(tái)的屬性支持,使得開發(fā)者能夠更輕松地操作和管理屬性。
示例代碼:
import java.util.Properties;
public class Example {
public static void main(String[] args) {
// 創(chuàng)建屬性對(duì)象
Properties props = new Properties();
// 設(shè)置屬性值
props.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");
props.setProperty("database.user", "root");
props.setProperty("database.password", "password");
// 獲取屬性值
String url = props.getProperty("database.url");
String user = props.getProperty("database.user");
String password = props.getProperty("database.password");
// 打印屬性值
System.out.println("URL: " + url);
System.out.println("User: " + user);
System.out.println("Password: " + password);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中增強(qiáng)的屬性支持功能,通過 Properties 類來操作和管理屬性,使得開發(fā)者能夠更輕松地處理配置信息。
JDK 21 引入了 JEP 442,該功能提供了數(shù)據(jù)化的 HTTP Client API,使得開發(fā)者能夠更靈活地操作 HTTP 請(qǐng)求和響應(yīng)數(shù)據(jù)。
示例代碼:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class Example {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.GET()
.build();
// 發(fā)送異步請(qǐng)求
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
// 處理異步響應(yīng)
future.thenAccept(response -> {
System.out.println("Response code: " + response.statusCode());
System.out.println("Response body: " + response.body());
});
// 阻塞主線程,等待異步請(qǐng)求完成
future.join();
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中數(shù)據(jù)化的 HTTP Client API,通過 CompletableFuture 實(shí)現(xiàn)異步發(fā)送 HTTP 請(qǐng)求,并處理異步響應(yīng)。
JDK 21 引入了 JEP 443,該功能提供了新的注釋 API,使得開發(fā)者能夠更方便地操作和處理 Java 源代碼中的注釋信息。
示例代碼:
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String value();
}
public class Example {
@MyAnnotation("Example annotation")
public void myMethod() {
// Method body
}
public static void main(String[] args) throws Exception {
Method method = Example.class.getMethod("myMethod");
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
if (annotation != null) {
System.out.println("Annotation value: " + annotation.value());
} else {
System.out.println("Annotation not found");
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中新的注釋 API,通過反射獲取方法上的注解信息并進(jìn)行處理。
JDK 21 引入了 JEP 445,該功能為 Java 增加了向量 API,使得開發(fā)者能夠更高效地進(jìn)行向量化操作,從而提升代碼的性能。
示例代碼:
import jdk.incubator.vector.*;
public class Example {
public static void main(String[] args) {
VectorSpecies<Float> species = FloatVector.SPECIES_256;
float[] a = new float[species.length()];
float[] b = new float[species.length()];
// 初始化數(shù)組
for (int i = 0; i < species.length(); i++) {
a[i] = i;
b[i] = i * 2;
}
// 使用向量化操作進(jìn)行數(shù)組加法
FloatVector va = FloatVector.fromArray(species, a, 0);
FloatVector vb = FloatVector.fromArray(species, b, 0);
FloatVector result = va.add(vb);
// 將結(jié)果寫回?cái)?shù)組
result.intoArray(a, 0);
// 打印結(jié)果數(shù)組
for (float f : a) {
System.out.println(f);
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的向量 API 進(jìn)行數(shù)組加法操作,通過向量化操作實(shí)現(xiàn)更高效的計(jì)算。
JDK 21 引入了 JEP 451,該功能增強(qiáng)了 Thread API,使得開發(fā)者能夠更方便地管理和操作線程。
示例代碼:
public class Example {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)新的線程
Thread thread = new Thread(() -> {
System.out.println("Thread is running...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread finished.");
});
// 設(shè)置線程名稱
thread.setName("MyThread");
// 啟動(dòng)線程
thread.start();
// 等待線程結(jié)束
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread finished.");
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中增強(qiáng)的 Thread API,包括設(shè)置線程名稱、等待線程結(jié)束等操作,使得開發(fā)者能夠更方便地管理和操作線程。
JDK 21 引入了 JEP 457,該功能改進(jìn)了 JVM 的垃圾收集器,使得其能夠更高效地管理內(nèi)存,提升應(yīng)用程序的性能和穩(wěn)定性。
示例代碼:
public class Example {
public static void main(String[] args) {
// 創(chuàng)建大量對(duì)象,觸發(fā)垃圾收集器
for (int i = 0; i < 1000000; i++) {
Object obj = new Object();
}
}
}
解釋:上面的示例代碼展示了如何創(chuàng)建大量對(duì)象以觸發(fā) JVM 的垃圾收集器,通過 JEP 457 改進(jìn)的垃圾收集器,可以更高效地管理這些對(duì)象,減少內(nèi)存泄漏和性能問題。
JDK 21 引入了 JEP 468,該功能改進(jìn)了 Java 中的線程安全性,使得開發(fā)者能夠更安全地在多線程環(huán)境中編寫并發(fā)程序。
示例代碼:
import java.util.concurrent.atomic.AtomicInteger;
public class Example {
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
// 創(chuàng)建多個(gè)線程對(duì)計(jì)數(shù)器進(jìn)行操作
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(() -> {
for (int j = 0; j < 1000; j++) {
count.incrementAndGet();
}
});
thread.start();
}
// 等待所有線程結(jié)束
Thread.sleep(1000);
// 打印計(jì)數(shù)器的值
System.out.println("Count: " + count);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的原子操作類 AtomicInteger 來確保在多線程環(huán)境中對(duì)計(jì)數(shù)器的安全操作,通過 JEP 468 改進(jìn)的線程安全性,可以避免出現(xiàn)競態(tài)條件和數(shù)據(jù)不一致的問題。
JDK 21 引入了 JEP 390,該功能提供了基于 Java 命令行工具的包管理工具,使得開發(fā)者能夠更方便地管理和使用第三方庫。
示例代碼:
## 在命令行中使用 jpm 安裝第三方庫
jpm install example-library
解釋:上面的示例代碼展示了如何使用 JDK 21 中的包管理工具 jpm 來安裝第三方庫,使得開發(fā)者能夠更方便地在項(xiàng)目中引入外部依賴。
JDK 21 引入了 JEP 395,該功能提供了基于文本的 UI 工具包,使得開發(fā)者能夠更輕松地創(chuàng)建命令行界面的用戶界面。
示例代碼:
import java.io.Console;
public class Example {
public static void main(String[] args) {
Console console = System.console();
if (console != null) {
console.printf("Enter your name: ");
String name = console.readLine();
console.printf("Hello, %s!\n", name);
} else {
System.err.println("No console available");
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中基于文本的 UI 工具包來創(chuàng)建一個(gè)簡單的命令行界面,使得開發(fā)者能夠更方便地與用戶進(jìn)行交互。
JDK 21 引入了 JEP 423,該功能使得在編譯時(shí)能夠檢查動(dòng)態(tài)生成的代碼,從而提前發(fā)現(xiàn)潛在的錯(cuò)誤。
示例代碼:
public class Example {
public static void main(String[] args) {
String code = """
public class GeneratedClass {
public void sayHello() {
System.out.println("Hello, world!");
}
}
""";
// 編譯動(dòng)態(tài)生成的代碼
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, code);
// 如果編譯成功,則加載并執(zhí)行動(dòng)態(tài)生成的類
if (result == 0) {
try {
Class<?> clazz = Class.forName("GeneratedClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
clazz.getMethod("sayHello").invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.err.println("Compilation failed");
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的編譯器 API,在運(yùn)行時(shí)動(dòng)態(tài)生成代碼并在編譯時(shí)進(jìn)行檢查,從而提前發(fā)現(xiàn)代碼中的錯(cuò)誤。
JDK 21 引入了 JEP 396,該功能提供了強(qiáng)大的打印和日志工具,使得開發(fā)者能夠更方便地輸出調(diào)試信息和記錄日志。
示例代碼:
import java.util.logging.*;
public class Example {
private static final Logger logger = Logger.getLogger(Example.class.getName());
public static void main(String[] args) {
logger.info("This is an informational message");
logger.warning("This is a warning message");
logger.severe("This is a severe message");
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中強(qiáng)大的日志工具,通過 Logger 類來輸出不同級(jí)別的日志信息,使得開發(fā)者能夠更方便地進(jìn)行調(diào)試和日志記錄。
JDK 21 引入了 JEP 397,該功能提供了 Unix 套接字通道,使得 Java 應(yīng)用程序能夠更輕松地與本地系統(tǒng)進(jìn)行通信。
示例代碼:
import java.io.*;
import java.net.*;
import java.nio.file.*;
public class Example {
public static void main(String[] args) throws IOException {
// 創(chuàng)建 Unix 套接字通道
Path socketFile = Paths.get("/tmp/mysocket");
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketFile);
try (UnixDomainSocketChannel channel = UnixDomainSocketChannel.open(address)) {
// 發(fā)送數(shù)據(jù)
String message = "Hello, Unix socket!";
channel.write(ByteBuffer.wrap(message.getBytes()));
// 讀取響應(yīng)
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
buffer.flip();
byte[] responseBytes = new byte[bytesRead];
buffer.get(responseBytes);
String response = new String(responseBytes);
System.out.println("Response: " + response);
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的 Unix 套接字通道來進(jìn)行進(jìn)程間通信,這使得 Java 應(yīng)用程序能夠更加靈活地與本地系統(tǒng)進(jìn)行交互。
JDK 21 引入了 JEP 398,該功能提供了統(tǒng)一的垃圾收集策略,使得開發(fā)者能夠更方便地配置和管理垃圾收集器。
示例代碼:
## 啟動(dòng) Java 應(yīng)用程序時(shí)通過參數(shù)配置統(tǒng)一的垃圾收集策略
java -XX:+UseZGC -jar myapp.jar
解釋:上面的示例代碼展示了如何使用 JDK 21 中的統(tǒng)一垃圾收集策略,在啟動(dòng) Java 應(yīng)用程序時(shí)通過參數(shù)來選擇合適的垃圾收集器,從而優(yōu)化應(yīng)用程序的性能和內(nèi)存管理。
JDK 21 引入了 JEP 400,該功能提供了 JDK 生態(tài)系統(tǒng)的更新機(jī)制,使得開發(fā)者能夠更方便地獲取和應(yīng)用 JDK 生態(tài)系統(tǒng)的更新。
示例代碼:
## 使用 jpackage 工具打包 Java 應(yīng)用程序并包含 JDK 生態(tài)系統(tǒng)的更新
jpackage --type app-image --name MyApp --input target/classes --main-jar myapp.jar --main-class com.example.MyApp --runtime-image /path/to/jdk21 --app-version 1.0
解釋:上面的示例代碼展示了如何使用 JDK 21 中的 jpackage 工具打包 Java 應(yīng)用程序,并在打包過程中包含 JDK 生態(tài)系統(tǒng)的更新,從而使得應(yīng)用程序能夠直接獲取更新的 JDK 生態(tài)系統(tǒng)。
JDK 21 引入了 JEP 401,該功能提供了基于容器的發(fā)布機(jī)制,使得開發(fā)者能夠更方便地將 Java 應(yīng)用程序打包成容器鏡像并進(jìn)行部署。
示例代碼:
## 使用 jlink 工具創(chuàng)建輕量級(jí)的運(yùn)行時(shí)鏡像
jlink --output my-runtime-image --add-modules java.base,java.logging,java.xml
## 使用 jpackage 工具打包 Java 應(yīng)用程序并包含運(yùn)行時(shí)鏡像
jpackage --type image --name MyApp --input target/classes --main-jar myapp.jar --main-class com.example.MyApp --runtime-image my-runtime-image --app-version 1.0
## 構(gòu)建容器鏡像
docker build -t myapp .
## 運(yùn)行容器
docker run -it --rm myapp
解釋:上面的示例代碼展示了如何使用 JDK 21 中的 jlink 和 jpackage 工具創(chuàng)建輕量級(jí)的運(yùn)行時(shí)鏡像,并將 Java 應(yīng)用程序打包成容器鏡像進(jìn)行部署。
JDK 21 引入了 JEP 404,該功能為 macOS 系統(tǒng)提供了 Z Garbage Collector(ZGC),使得開發(fā)者能夠在 macOS 平臺(tái)上使用低延遲的垃圾收集器。
示例代碼:
## 啟用 ZGC 垃圾收集器運(yùn)行 Java 應(yīng)用程序
java -XX:+UseZGC -jar myapp.jar
解釋:上面的示例代碼展示了如何在 macOS 系統(tǒng)上啟用 ZGC 垃圾收集器來運(yùn)行 Java 應(yīng)用程序,從而實(shí)現(xiàn)低延遲和高吞吐量的垃圾收集。
JDK 21 引入了 JEP 407,該功能提高了 Java 的安全性,包括修復(fù)了一些安全漏洞和弱點(diǎn),并增強(qiáng)了安全特性。
示例代碼:
public class Example {
public static void main(String[] args) {
// 安全地處理用戶輸入
String userInput = args[0];
String sanitizedInput = sanitize(userInput);
// 繼續(xù)處理經(jīng)過安全處理的用戶輸入
}
private static String sanitize(String input) {
// 進(jìn)行輸入驗(yàn)證和過濾,確保不包含惡意代碼
// 返回經(jīng)過安全處理的輸入
return input.replaceAll("<", "").replaceAll(">", "");
}
}
解釋:上面的示例代碼展示了如何在 Java 應(yīng)用程序中安全地處理用戶輸入,通過輸入驗(yàn)證和過濾來防止惡意代碼的注入,提高應(yīng)用程序的安全性。
JDK 21 引入了 JEP 409,該功能提供了應(yīng)用程序類數(shù)據(jù)共享(AppCDS),使得多個(gè) Java 應(yīng)用程序能夠共享同一份類數(shù)據(jù),減少內(nèi)存占用和啟動(dòng)時(shí)間。
示例代碼:
## 使用 jlink 工具創(chuàng)建包含應(yīng)用程序類數(shù)據(jù)共享的運(yùn)行時(shí)鏡像
jlink --output my-runtime-image --add-modules java.base,java.logging,java.xml --class-for-name com.example.MyClass
## 使用 jpackage 工具打包 Java 應(yīng)用程序并包含運(yùn)行時(shí)鏡像
jpackage --type image --name MyApp --input target/classes --main-jar myapp.jar --main-class com.example.MyApp --runtime-image my-runtime-image --app-version 1.0
解釋:上面的示例代碼展示了如何使用 JDK 21 中的 jlink 工具創(chuàng)建包含應(yīng)用程序類數(shù)據(jù)共享的運(yùn)行時(shí)鏡像,并使用 jpackage 工具打包 Java 應(yīng)用程序,從而實(shí)現(xiàn)多個(gè)應(yīng)用程序共享同一份類數(shù)據(jù),減少內(nèi)存占用和啟動(dòng)時(shí)間。
JDK 21 引入了 JEP 412,該功能在 Windows 平臺(tái)上啟用了 AOT(Ahead-of-Time)編譯器,使得開發(fā)者能夠?qū)?Java 應(yīng)用程序編譯成本地機(jī)器代碼,提高應(yīng)用程序的性能。
示例代碼:
## 使用 jaotc 工具將 Java 應(yīng)用程序編譯成本地機(jī)器代碼
jaotc --output myapp.dll --module mymodule
解釋:上面的示例代碼展示了如何使用 JDK 21 中的 jaotc 工具將 Java 應(yīng)用程序編譯成本地機(jī)器代碼,從而提高應(yīng)用程序的性能。
JDK 21 引入了 JEP 414,該功能為向量API提供了第二個(gè)版本,包括更多的操作和改進(jìn),使得開發(fā)者能夠更高效地利用硬件向量化指令。
示例代碼:
import jdk.incubator.vector.*;
public class Example {
public static void main(String[] args) {
VectorSpecies<Float> species = FloatVector.SPECIES_256;
float[] a = new float[species.length()];
float[] b = new float[species.length()];
// 初始化數(shù)組
for (int i = 0; i < species.length(); i++) {
a[i] = i;
b[i] = i * 2;
}
// 使用向量化操作進(jìn)行數(shù)組加法
FloatVector va = FloatVector.fromArray(species, a, 0);
FloatVector vb = FloatVector.fromArray(species, b, 0);
FloatVector result = va.add(vb);
// 將結(jié)果寫回?cái)?shù)組
result.intoArray(a, 0);
// 打印結(jié)果數(shù)組
for (float f : a) {
System.out.println(f);
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的向量API v2.0進(jìn)行數(shù)組加法操作,通過向量化操作實(shí)現(xiàn)更高效的計(jì)算。
JDK 21 引入了 JEP 416,該功能提供了改進(jìn)的 AArch64(ARM 64位架構(gòu))程序計(jì)數(shù)器模型,使得在 ARM 64位架構(gòu)上的 Java 應(yīng)用程序能夠更好地執(zhí)行和調(diào)試。
示例代碼:
## 編譯和運(yùn)行 Java 應(yīng)用程序
javac MyApp.java
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly MyApp
解釋:上面的示例代碼展示了如何使用 JDK 21 在 ARM 64位架構(gòu)上編譯和運(yùn)行 Java 應(yīng)用程序,并使用診斷選項(xiàng)和打印匯編輸出來調(diào)試程序執(zhí)行情況。
JDK 21 引入了 JEP 419,該功能提供了 Unix 套接字通道 API 的第二個(gè)版本,包括更多的操作和改進(jìn),使得開發(fā)者能夠更靈活地在 Unix 系統(tǒng)上進(jìn)行進(jìn)程間通信。
示例代碼:
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.*;
public class Example {
public static void main(String[] args) throws IOException {
try (UnixDomainSocketChannel channel = UnixDomainSocketChannel.open()) {
// 連接到指定的 Unix 套接字地址
SocketAddress address = UnixDomainSocketAddress.of("/tmp/mysocket");
channel.connect(address);
// 發(fā)送數(shù)據(jù)
channel.write(ByteBuffer.wrap("Hello, Unix socket!".getBytes()));
// 讀取響應(yīng)
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
buffer.flip();
byte[] responseBytes = new byte[bytesRead];
buffer.get(responseBytes);
String response = new String(responseBytes);
System.out.println("Response: " + response);
}
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的 Unix 套接字通道 API v2 進(jìn)行進(jìn)程間通信,包括連接到指定的 Unix 套接字地址、發(fā)送數(shù)據(jù)和讀取響應(yīng)等操作。
JDK 21 引入了 JEP 420,該功能簡化了泛型參數(shù)的命名規(guī)范,使得開發(fā)者能夠更清晰地理解泛型類型和方法的含義。
示例代碼:
import java.util.List;
public class Example {
public static void main(String[] args) {
// 使用簡化的泛型參數(shù)名稱
List<String> list = List.of("apple", "banana", "orange");
String first = list.get(0);
System.out.println("First element: " + first);
}
}
解釋:上面的示例代碼展示了如何使用 JDK 21 中的簡化泛型參數(shù)名稱特性,使得開發(fā)者能夠更清晰地閱讀和理解泛型類型和方法的含義。
好了,以上是 V 哥在學(xué)習(xí) JDK21的過程中總結(jié)的35個(gè)新特性,有了這些新特性的加持,對(duì) Java 開發(fā)的應(yīng)用在安全、穩(wěn)定、簡化復(fù)雜代碼、構(gòu)建和部署、可靠性、并發(fā)、模塊化等方面,有了更好的支持。兄弟們,收藏起來慢慢學(xué)習(xí),最后,V 哥想說一句,整理不易,如果這篇內(nèi)容對(duì)你有幫助,也希望可以分享給更多學(xué)習(xí) Java 的小伙伴,你還知道 JDK21有哪些新特性嗎,V 哥歡迎留言分享給我,在此先謝過!JDK 21
更多建議: