当前位置: 首页 > news >正文

JDK 21 API增强详解

JDK 21 API增强详解

1. Sequenced Collections(序列化集合)

特性概述

Sequenced Collections为Java集合框架添加了统一的顺序访问API。这个特性解决了不同集合类型(List、Set、Map)在顺序操作上API不一致的问题,提供了更统一和直观的接口。

技术细节

Sequenced Collections引入的核心接口和方法:

  • SequencedCollection<E>:顺序集合的根接口
  • SequencedSet<E>:顺序Set接口
  • SequencedMap<K,V>:顺序Map接口
  • 统一的顺序操作方法:getFirst(), getLast(), reversed()

代码示例

// Sequenced Collections基本使用
import java.util.*;public class SequencedCollectionsExample {public static void main(String[] args) {// List作为SequencedCollection使用List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));demonstrateSequencedCollection(list);// LinkedHashSet作为SequencedSet使用Set<String> set = new LinkedHashSet<>(Arrays.asList("X", "Y", "Z"));demonstrateSequencedSet(set);// LinkedHashMap作为SequencedMap使用Map<String, Integer> map = new LinkedHashMap<>();map.put("first", 1);map.put("second", 2);map.put("third", 3);demonstrateSequencedMap(map);}public static void demonstrateSequencedCollection(SequencedCollection<String> collection) {System.out.println("=== Sequenced Collection Demo ===");System.out.println("Original: " + collection);System.out.println("First element: " + collection.getFirst());System.out.println("Last element: " + collection.getLast());// 反转视图SequencedCollection<String> reversed = collection.reversed();System.out.println("Reversed: " + reversed);System.out.println("First in reversed: " + reversed.getFirst());System.out.println("Last in reversed: " + reversed.getLast());// 添加元素到开头和结尾collection.addFirst("START");collection.addLast("END");System.out.println("After adding: " + collection);System.out.println();}public static void demonstrateSequencedSet(SequencedSet<String> set) {System.out.println("=== Sequenced Set Demo ===");System.out.println("Original: " + set);System.out.println("First element: " + set.getFirst());System.out.println("Last element: " + set.getLast());// 反转视图SequencedSet<String> reversed = set.reversed();System.out.println("Reversed: " + reversed);// 添加元素set.addFirst("BEGIN");set.addLast("FINISH");System.out.println("After adding: " + set);System.out.println();}public static void demonstrateSequencedMap(SequencedMap<String, Integer> map) {System.out.println("=== Sequenced Map Demo ===");System.out.println("Original: " + map);System.out.println("First entry: " + map.firstEntry());System.out.println("Last entry: " + map.lastEntry());// 反转视图SequencedMap<String, Integer> reversed = map.reversed();System.out.println("Reversed: " + reversed);System.out.println("First entry in reversed: " + reversed.firstEntry());// 添加条目到开头和结尾map.putFirst("zero", 0);map.putLast("four", 4);System.out.println("After adding: " + map);System.out.println();}
}// 实际应用场景
public class SequencedCollectionsUseCases {// 统一处理不同类型的顺序集合public static <E> void processSequencedCollection(SequencedCollection<E> collection) {if (collection.isEmpty()) {System.out.println("Collection is empty");return;}System.out.println("Processing collection: " + collection);System.out.println("First element: " + collection.getFirst());System.out.println("Last element: " + collection.getLast());System.out.println("Size: " + collection.size());// 反向处理System.out.println("Reverse processing:");collection.reversed().forEach(System.out::println);}// 队列操作的简化public static <E> void demonstrateQueueOperations(SequencedCollection<E> collection) {// 添加到队尾collection.addLast((E) "New Item");System.out.println("After enqueue: " + collection);// 从队头移除E first = collection.removeFirst();System.out.println("Dequeued: " + first);System.out.println("After dequeue: " + collection);}// 栈操作的简化public static <E> void demonstrateStackOperations(SequencedCollection<E> collection) {// 压栈collection.addFirst((E) "Stack Item");System.out.println("After push: " + collection);// 弹栈E last = collection.removeFirst();System.out.println("Popped: " + last);System.out.println("After pop: " + collection);}// Map的顺序操作public static <K, V> void demonstrateMapSequencing(SequencedMap<K, V> map) {System.out.println("Map entries in order:");map.sequencedEntrySet().forEach(entry -> System.out.println(entry.getKey() + " -> " + entry.getValue()));System.out.println("Keys in order:");map.sequencedKeySet().forEach(System.out::println);System.out.println("Values in order:");map.sequencedValues().forEach(System.out::println);}
}// 自定义Sequenced Collection实现
public class CustomSequencedCollection<E> implements SequencedCollection<E> {private final Deque<E> deque = new ArrayDeque<>();@Overridepublic int size() {return deque.size();}@Overridepublic boolean isEmpty() {return deque.isEmpty();}@Overridepublic boolean contains(Object o) {return deque.contains(o);}@Overridepublic Iterator<E> iterator() {return deque.iterator();}@Overridepublic Object[] toArray() {return deque.toArray();}@Overridepublic <T> T[] toArray(T[] a) {return deque.toArray(a);}@Overridepublic boolean add(E e) {return deque.add(e);}@Overridepublic boolean remove(Object o) {return deque.remove(o);}@Overridepublic boolean containsAll(Collection<?> c) {return deque.containsAll(c);}@Overridepublic boolean addAll(Collection<? extends E> c) {return deque.addAll(c);}@Overridepublic boolean removeAll(Collection<?> c) {return deque.removeAll(c);}@Overridepublic boolean retainAll(Collection<?> c) {return deque.retainAll(c);}@Overridepublic void clear() {deque.clear();}// SequencedCollection特有的方法@Overridepublic E getFirst() {if (isEmpty()) {throw new NoSuchElementException();}return deque.getFirst();}@Overridepublic E getLast() {if (isEmpty()) {throw new NoSuchElementException();}return deque.getLast();}@Overridepublic void addFirst(E e) {deque.addFirst(e);}@Overridepublic void addLast(E e) {deque.addLast(e);}@Overridepublic E removeFirst() {if (isEmpty()) {throw new NoSuchElementException();}return deque.removeFirst();}@Overridepublic E removeLast() {if (isEmpty()) {throw new NoSuchElementException();}return deque.removeLast();}@Overridepublic SequencedCollection<E> reversed() {return new ReversedSequencedCollection<>(this);}// Reversed view implementationprivate static class ReversedSequencedCollection<E> implements SequencedCollection<E> {private final SequencedCollection<E> original;ReversedSequencedCollection(SequencedCollection<E> original) {this.original = original;}@Overridepublic int size() {return original.size();}@Overridepublic boolean isEmpty() {return original.isEmpty();}@Overridepublic boolean contains(Object o) {return original.contains(o);}@Overridepublic Iterator<E> iterator() {return original.reversed().iterator();}@Overridepublic Object[] toArray() {Object[] array = original.toArray();Collections.reverse(Arrays.asList(array));return array;}@Overridepublic <T> T[] toArray(T[] a) {T[] array = original.toArray(a);Collections.reverse(Arrays.asList(array));return array;}@Overridepublic boolean add(E e) {return original.add(e);}@Overridepublic boolean remove(Object o) {return original.remove(o);}@Overridepublic boolean containsAll(Collection<?> c) {return original.containsAll(c);}@Overridepublic boolean addAll(Collection<? extends E> c) {return original.addAll(c);}@Overridepublic boolean removeAll(Collection<?> c) {return original.removeAll(c);}@Overridepublic boolean retainAll(Collection<?> c) {return original.retainAll(c);}@Overridepublic void clear() {original.clear();}@Overridepublic E getFirst() {return original.getLast();}@Overridepublic E getLast() {return original.getFirst();}@Overridepublic void addFirst(E e) {original.addLast(e);}@Overridepublic void addLast(E e) {original.addFirst(e);}@Overridepublic E removeFirst() {return original.removeLast();}@Overridepublic E removeLast() {return original.removeFirst();}@Overridepublic SequencedCollection<E> reversed() {return original;}}
}

使用建议

  1. 适用场景

    • 需要统一处理不同顺序集合的场景
    • 简化队列和栈操作
    • 需要反向遍历集合的场景
  2. 最佳实践

    • 优先使用SequencedCollection接口而非具体实现类
    • 合理利用reversed()方法进行反向操作
    • 在API设计中考虑使用Sequenced Collection接口
  3. 注意事项

    • 注意不同集合类型对顺序的保证程度
    • HashSet等无序集合不实现SequencedSet接口
    • 合理处理空集合的异常情况

2. String Templates(字符串模板,预览特性)

特性概述

String Templates是JDK 21中的预览特性,提供了字符串插值的新方式。它比传统的字符串拼接更安全、更高效,并且支持模板表达式的验证。

技术细节

String Templates的核心组件:

  • TemplateProcessor:处理模板的接口
  • STR:内置的字符串模板处理器
  • FMT:格式化字符串模板处理器
  • 模板表达式语法:使用\{expression}形式

代码示例

// 需要添加JVM参数:--enable-preview --source 21// String Templates基本使用
public class StringTemplatesExample {public static void main(String[] args) {// 基本字符串模板String name = "Alice";int age = 30;String message = STR."Hello, \{name}! You are \{age} years old.";System.out.println(message);// 复杂表达式List<String> items = Arrays.asList("Apple", "Banana", "Orange");String listMessage = STR."Items: \{String.join(", ", items)}";System.out.println(listMessage);// 嵌套模板String greeting = STR."Welcome, \{name}!";String fullMessage = STR."\{greeting} Today is \{LocalDate.now()}";System.out.println(fullMessage);// 使用FMT进行格式化double price = 123.456;String formatted = FMT."Price: $\{price%.2f}";System.out.println(formatted);// 多行模板String multiLine = STR."""User Information:Name: \{name}Age: \{age}Items: \{String.join(", ", items)}""";System.out.println(multiLine);}// 实际应用场景public static void demonstrateUseCases() {// SQL查询模板String tableName = "users";String condition = "age > 18";String sql = STR."SELECT * FROM \{tableName} WHERE \{condition}";System.out.println("SQL: " + sql);// JSON生成模板String username = "john_doe";String email = "john@example.com";String json = STR."""{"username": "\{username}","email": "\{email}","created": "\{LocalDateTime.now()}"}""";System.out.println("JSON: " + json);// 日志消息模板String methodName = "processData";int recordCount = 1000;String logMessage = STR."[\{LocalTime.now()}] \{methodName}: Processed \{recordCount} records";System.out.println("Log: " + logMessage);}// 自定义模板处理器public static void customTemplateProcessor() {// 创建自定义模板处理器TemplateProcessor<String> upperCaseProcessor = TemplateProcessor.of((template, values) -> {String result = template.interpolate(values);return result.toUpperCase();});String name = "alice";String greeting = upperCaseProcessor."Hello, \{name}!";System.out.println(greeting);  // 输出: HELLO, ALICE!}// 安全性示例public static void securityExample() {// 传统的字符串拼接可能存在的安全问题String userInput = "'; DROP TABLE users; --";// 不安全的方式(示例)// String unsafeQuery = "SELECT * FROM users WHERE name = '" + userInput + "'";// 使用模板的安全方式String safeQuery = STR."SELECT * FROM users WHERE name = '\{userInput}'";System.out.println("Safe query: " + safeQuery);// 模板会自动处理特殊字符的转义}
}

使用建议

  1. 适用场景

    • 需要字符串插值的场景
    • 生成SQL查询、JSON、XML等结构化文本
    • 日志消息格式化
  2. 最佳实践

    • 优先使用STR和FMT内置处理器
    • 在多行文本中使用字符串模板
    • 注意模板表达式的复杂度
  3. 注意事项

    • 这是预览特性,API可能发生变化
    • 需要启用预览特性才能使用
    • 注意模板表达式的性能影响

3. Scoped Values(作用域值,预览特性)

特性概述

Scoped Values是JDK 21中的预览特性,提供了在线程内和线程间共享不可变数据的新方式。它是ThreadLocal的现代化替代方案,特别适合与虚拟线程一起使用。

技术细节

Scoped Values的核心特性:

  • 不可变性:一旦设置就不能修改
  • 作用域绑定:在特定代码块内绑定值
  • 线程继承:子线程可以访问父线程的作用域值
  • 与虚拟线程兼容:比ThreadLocal更适合虚拟线程

代码示例

// 需要添加JVM参数:--enable-preview --source 21import jdk.incubator.concurrent.ScopedValue;public class ScopedValuesExample {// 定义作用域值private static final ScopedValue<String> USER_ID = ScopedValue.newInstance();private static final ScopedValue<String> REQUEST_ID = ScopedValue.newInstance();private static final ScopedValue<Boolean> DEBUG_MODE = ScopedValue.newInstance();public static void main(String[] args) {// 基本使用ScopedValue.where(USER_ID, "user123").where(REQUEST_ID, "req456").where(DEBUG_MODE, true).run(() -> {processRequest();});}public static void processRequest() {// 在作用域内访问值System.out.println("User ID: " + USER_ID.get());System.out.println("Request ID: " + REQUEST_ID.get());System.out.println("Debug mode: " + DEBUG_MODE.get());// 调用其他方法performDatabaseOperation();callExternalService();}public static void performDatabaseOperation() {// 在同一线程中访问作用域值String userId = USER_ID.get();String requestId = REQUEST_ID.get();System.out.println("DB Operation - User: " + userId + ", Request: " + requestId);// 创建子线程(虚拟线程)Thread.ofVirtual().start(() -> {// 子线程可以访问父线程的作用域值System.out.println("Virtual Thread - User: " + USER_ID.get() + ", Request: " + REQUEST_ID.get());});}public static void callExternalService() {// 嵌套作用域ScopedValue.where(DEBUG_MODE, false).run(() -> {System.out.println("External Service - Debug: " + DEBUG_MODE.get());// 调用外部服务});}// 实际应用场景public static void webFrameworkExample() {// 模拟Web框架中的请求处理String userId = "user789";String requestId = java.util.UUID.randomUUID().toString();boolean isDebug = true;ScopedValue.where(USER_ID, userId).where(REQUEST_ID, requestId).where(DEBUG_MODE, isDebug).run(() -> {handleHttpRequest();});}public static void handleHttpRequest() {// 记录请求信息logInfo("Handling request for user: " + USER_ID.get());// 业务逻辑处理processData();// 响应处理sendResponse();}public static void processData() {if (DEBUG_MODE.get()) {logDebug("Processing data for request: " + REQUEST_ID.get());}// 模拟数据处理// 创建多个虚拟线程处理并发任务List<Thread> threads = new ArrayList<>();for (int i = 0; i < 5; i++) {final int taskId = i;Thread vt = Thread.ofVirtual().start(() -> {// 虚拟线程可以访问作用域值logInfo("Task " + taskId + " processing for user: " + USER_ID.get());});threads.add(vt);}// 等待所有任务完成threads.forEach(thread -> {try {thread.join();} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}public static void sendResponse() {logInfo("Sending response for request: " + REQUEST_ID.get());}// 日志方法使用作用域值public static void logInfo(String message) {System.out.println("[INFO] [" + REQUEST_ID.get() + "] " + message);}public static void logDebug(String message) {if (DEBUG_MODE.get()) {System.out.println("[DEBUG] [" + REQUEST_ID.get() + "] " + message);}}// 与传统ThreadLocal的对比public static void compareWithThreadLocal() {// ThreadLocal方式ThreadLocal<String> userIdTL = new ThreadLocal<>();userIdTL.set("user123");System.out.println("ThreadLocal value: " + userIdTL.get());userIdTL.remove();// Scoped Value方式ScopedValue<String> userIdSV = ScopedValue.newInstance();ScopedValue.where(userIdSV, "user123").run(() -> {System.out.println("Scoped Value: " + userIdSV.get());});// 作用域结束后自动清理}
}

使用建议

  1. 适用场景

    • 跨方法传递上下文信息
    • Web应用中的请求上下文
    • 与虚拟线程一起使用的场景
  2. 最佳实践

    • 优先使用Scoped Values替代ThreadLocal
    • 在需要跨线程共享数据时使用
    • 合理设计作用域的边界
  3. 注意事项

    • 这是预览特性,API可能发生变化
    • 需要启用预览特性才能使用
    • 作用域值是不可变的,不能修改

4. Key Encapsulation Mechanism API(密钥封装机制API)

特性概述

Key Encapsulation Mechanism API为后量子密码学提供了支持,允许使用后量子加密算法进行密钥封装和解封装操作。

技术细节

KEM API的核心组件:

  • KeyEncapsulationMechanism:密钥封装机制接口
  • KEM:KEM工厂类
  • SecretKey:封装的密钥
  • 支持多种后量子加密算法

代码示例

// Key Encapsulation Mechanism API示例
import javax.crypto.KEM;
import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;public class KEMExample {public static void main(String[] args) {try {// 创建密钥对KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");kpg.initialize(256);KeyPair keyPair = kpg.generateKeyPair();// 注意:JDK 21中的KEM API主要用于后量子加密// 这里展示API的使用方式,实际使用需要相应的后量子算法支持System.out.println("KEM API演示框架");System.out.println("密钥对已生成");} catch (Exception e) {e.printStackTrace();}}// KEM使用示例(概念性)public static void demonstrateKEMUsage() {/*// 获取KEM实例(需要后量子算法支持)KEM kem = KEM.getInstance("CRYSTALS-Kyber");// 生成密钥对KEM.KeyPairGenerator kpg = kem.newKeyPairGenerator();KEM.KeyPair keyPair = kpg.generateKeyPair();// 发送方:封装密钥KEM.Encapsulator encapsulator = kem.newEncapsulator(keyPair.getPublic());KEM.Encapsulated encap = encapsulator.encapsulate();// 接收方:解封装密钥KEM.Decapsulator decapsulator = kem.newDecapsulator(keyPair.getPrivate());SecretKey sharedSecret = decapsulator.decapsulate(encap.encapsulation());System.out.println("密钥封装完成");*/}
}

总结

JDK 21的API增强主要集中在以下几个方面:

  1. Sequenced Collections:提供了统一的顺序集合API,简化了集合操作
  2. String Templates:提供了更安全、更高效的字符串插值方式
  3. Scoped Values:提供了现代化的线程本地变量替代方案
  4. KEM API:为后量子加密提供了支持

这些API增强不仅提高了Java平台的功能性,还增强了开发者的编程体验,为构建更安全、更高效的应用程序提供了更好的工具支持。

http://www.dtcms.com/a/516784.html

相关文章:

  • 化妆品可做的团购网站有哪些有个能写文章做任务的网站
  • 【JVM】详解 类加载器与类加载过程
  • 织梦移动网站模板免费下载佛山国内快速建站
  • 九九乘法表(C语言)
  • AI赋能:下一代海外社媒推广的智能化路径
  • i2c 时序解析
  • 基于线程池的配电房图像检测
  • 天河网站+建设信科网络龙口网页设计
  • 企业官网网站建设咨询手机网站模板下载免费
  • 线性代数直觉(三):特征值(eigenvalue)与特征向量(eigenvector)为何物?
  • 学生个人网站建设模板郑州开发软件公司
  • [Agent可视化] 智能体核心(Rust) | WASI沙箱 | `grpc_server.rs`
  • 东莞网站建设方案托管桂林做网站的公司有哪些
  • 所有搜索引擎蜘蛛不来网站了最新军事报道
  • Java | Lombok @Builder.Default 排障指南:为什么 build 时默认值丢失?
  • 东莞网站快速优化排名中国品牌网站建设
  • 计算机网络 网站代理公司注册新公司的费用
  • Linux下的TCP滑动窗口
  • 从CCLKIE到EtherCAT:汇川PLC在大型选矿厂的伺服通讯升级之路
  • wordpress 建站 知乎app开发app制作公司
  • wordpress代码创建子站点建设谷歌公司网站费用
  • 多资产回测实战 | 用 DolphinDB 搭建股票期货对冲与期权套利策略
  • 企业营销管理软件网站优化查询
  • 数字孪生大屏实战:山海鲸可视化如何让制造业‘透明化
  • Linux 内存 --- get_user_pages/pin_user_pages函数
  • 《探索 Docker+Neko+cpolar 实现跨网共享浏览器的无限可能》
  • 调用百度云语音识别服务——实现c++接口识别语音
  • 浅谈常见的八类数据库加密技术
  • Beyond Compare 5 for Mac 好用的文件对比工具
  • 济南专业做网站公司哪家好做爰全过程免费的视频凤凰网站