深入解析: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<>();
                                @Override
                                public int size() {
                                return deque.size();
                                }
                                @Override
                                public boolean isEmpty() {
                                return deque.isEmpty();
                                }
                                @Override
                                public boolean contains(Object o) {
                                return deque.contains(o);
                                }
                                @Override
                                public Iterator<E> iterator() {
                                  return deque.iterator();
                                  }
                                  @Override
                                  public Object[] toArray() {
                                  return deque.toArray();
                                  }
                                  @Override
                                  public <T> T[] toArray(T[] a) {
                                    return deque.toArray(a);
                                    }
                                    @Override
                                    public boolean add(E e) {
                                    return deque.add(e);
                                    }
                                    @Override
                                    public boolean remove(Object o) {
                                    return deque.remove(o);
                                    }
                                    @Override
                                    public boolean containsAll(Collection<?> c) {
                                      return deque.containsAll(c);
                                      }
                                      @Override
                                      public boolean addAll(Collection<? extends E> c) {
                                        return deque.addAll(c);
                                        }
                                        @Override
                                        public boolean removeAll(Collection<?> c) {
                                          return deque.removeAll(c);
                                          }
                                          @Override
                                          public boolean retainAll(Collection<?> c) {
                                            return deque.retainAll(c);
                                            }
                                            @Override
                                            public void clear() {
                                            deque.clear();
                                            }
                                            // SequencedCollection特有的方法
                                            @Override
                                            public E getFirst() {
                                            if (isEmpty()) {
                                            throw new NoSuchElementException();
                                            }
                                            return deque.getFirst();
                                            }
                                            @Override
                                            public E getLast() {
                                            if (isEmpty()) {
                                            throw new NoSuchElementException();
                                            }
                                            return deque.getLast();
                                            }
                                            @Override
                                            public void addFirst(E e) {
                                            deque.addFirst(e);
                                            }
                                            @Override
                                            public void addLast(E e) {
                                            deque.addLast(e);
                                            }
                                            @Override
                                            public E removeFirst() {
                                            if (isEmpty()) {
                                            throw new NoSuchElementException();
                                            }
                                            return deque.removeFirst();
                                            }
                                            @Override
                                            public E removeLast() {
                                            if (isEmpty()) {
                                            throw new NoSuchElementException();
                                            }
                                            return deque.removeLast();
                                            }
                                            @Override
                                            public SequencedCollection<E> reversed() {
                                              return new ReversedSequencedCollection<>(this);
                                                }
                                                // Reversed view implementation
                                                private static class ReversedSequencedCollection<E>
                                                  implements SequencedCollection<E> {
                                                    private final SequencedCollection<E> original;
                                                      ReversedSequencedCollection(SequencedCollection<E> original) {
                                                        this.original = original;
                                                        }
                                                        @Override
                                                        public int size() {
                                                        return original.size();
                                                        }
                                                        @Override
                                                        public boolean isEmpty() {
                                                        return original.isEmpty();
                                                        }
                                                        @Override
                                                        public boolean contains(Object o) {
                                                        return original.contains(o);
                                                        }
                                                        @Override
                                                        public Iterator<E> iterator() {
                                                          return original.reversed().iterator();
                                                          }
                                                          @Override
                                                          public Object[] toArray() {
                                                          Object[] array = original.toArray();
                                                          Collections.reverse(Arrays.asList(array));
                                                          return array;
                                                          }
                                                          @Override
                                                          public <T> T[] toArray(T[] a) {
                                                            T[] array = original.toArray(a);
                                                            Collections.reverse(Arrays.asList(array));
                                                            return array;
                                                            }
                                                            @Override
                                                            public boolean add(E e) {
                                                            return original.add(e);
                                                            }
                                                            @Override
                                                            public boolean remove(Object o) {
                                                            return original.remove(o);
                                                            }
                                                            @Override
                                                            public boolean containsAll(Collection<?> c) {
                                                              return original.containsAll(c);
                                                              }
                                                              @Override
                                                              public boolean addAll(Collection<? extends E> c) {
                                                                return original.addAll(c);
                                                                }
                                                                @Override
                                                                public boolean removeAll(Collection<?> c) {
                                                                  return original.removeAll(c);
                                                                  }
                                                                  @Override
                                                                  public boolean retainAll(Collection<?> c) {
                                                                    return original.retainAll(c);
                                                                    }
                                                                    @Override
                                                                    public void clear() {
                                                                    original.clear();
                                                                    }
                                                                    @Override
                                                                    public E getFirst() {
                                                                    return original.getLast();
                                                                    }
                                                                    @Override
                                                                    public E getLast() {
                                                                    return original.getFirst();
                                                                    }
                                                                    @Override
                                                                    public void addFirst(E e) {
                                                                    original.addLast(e);
                                                                    }
                                                                    @Override
                                                                    public void addLast(E e) {
                                                                    original.addFirst(e);
                                                                    }
                                                                    @Override
                                                                    public E removeFirst() {
                                                                    return original.removeLast();
                                                                    }
                                                                    @Override
                                                                    public E removeLast() {
                                                                    return original.removeFirst();
                                                                    }
                                                                    @Override
                                                                    public 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 21
import 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平台的功能性,还增强了开发者的编程体验,为构建更安全、更高效的应用程序提供了更好的工具支持。

posted @ 2025-11-21 22:47  clnchanpin  阅读(47)  评论(0)    收藏  举报