第70章

Java 21新特性

掌握Java 21 LTS版本的最新特性:虚拟线程、模式匹配增强、字符串模板等

学习目标

Java 21概述

Java 21是Oracle在2023年9月发布的长期支持(LTS)版本,继Java 17之后的又一个重要里程碑。作为LTS版本,Java 21将获得长期的支持和维护,是企业级应用的理想选择。

为什么选择Java 21?

Java 21引入了多项革命性特性,特别是虚拟线程的正式发布,极大地简化了并发编程。同时,模式匹配、字符串模板等特性让代码更加简洁和表达力更强。

Java版本演进时间线

Java 8
2014年3月 - LTS
Lambda表达式、Stream API、方法引用
Java 11
2018年9月 - LTS
HTTP Client、局部变量类型推断、字符串增强
Java 17
2021年9月 - LTS
密封类、模式匹配、文本块、记录类
Java 21
2023年9月 - LTS
虚拟线程、模式匹配增强、字符串模板、序列化集合

Java 21主要新特性

虚拟线程(Virtual Threads)

基本使用示例:
// 创建虚拟线程
Thread virtualThread = Thread.ofVirtual()
    .name("virtual-thread-1")
    .start(() -> {
        System.out.println("运行在虚拟线程中");
    });

// 使用虚拟线程执行器
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> {
        // 任务代码
        return "虚拟线程执行结果";
    });
}
  • 轻量级线程,可创建数百万个
  • 简化并发编程模型
  • 提高应用程序吞吐量
  • 减少内存占用

模式匹配增强

Switch表达式模式匹配:
// 模式匹配with switch
String result = switch (obj) {
    case String s -> "字符串: " + s;
    case Integer i -> "整数: " + i;
    case List list -> "列表大小: " + list.size();
    case null -> "空值";
    default -> "未知类型";
};

// 守卫条件
String classify = switch (obj) {
    case String s when s.length() > 10 -> "长字符串";
    case String s -> "短字符串";
    case Integer i when i > 0 -> "正整数";
    case Integer i -> "非正整数";
    default -> "其他类型";
};
  • 类型模式匹配
  • 守卫条件支持
  • 更安全的类型转换
  • 代码更简洁易读

字符串模板(预览)

字符串模板语法:
// 字符串模板基本用法
String name = "张三";
int age = 25;
String message = STR."你好,\{name}!你今年\{age}岁了。";

// 表达式插值
int x = 10, y = 20;
String calculation = STR."\{x} + \{y} = \{x + y}";

// 多行字符串模板
String html = STR."""
    

\{title}

\{content}

""";
  • 类型安全的字符串插值
  • 支持表达式计算
  • 多行字符串支持
  • 编译时验证

序列化集合

序列化集合API:
// SequencedCollection接口
List list = new ArrayList<>();
list.addFirst("第一个");
list.addLast("最后一个");
String first = list.getFirst();
String last = list.getLast();

// SequencedSet接口
LinkedHashSet set = new LinkedHashSet<>();
set.addFirst(1);
set.addLast(3);
SequencedSet reversed = set.reversed();

// SequencedMap接口
LinkedHashMap map = new LinkedHashMap<>();
map.putFirst("first", 1);
map.putLast("last", 100);
Entry firstEntry = map.firstEntry();
  • 统一的序列化集合接口
  • 首尾元素操作方法
  • 反向视图支持
  • 更直观的API设计

虚拟线程详解

虚拟线程是Java 21最重要的特性之一,它们是轻量级的线程,由JVM管理而不是操作系统。虚拟线程使得编写高并发应用程序变得更加简单。

虚拟线程 vs 平台线程

特性 平台线程 虚拟线程
创建成本 高(约2MB栈空间) 低(几KB)
最大数量 数千个 数百万个
调度方式 操作系统调度 JVM调度
阻塞行为 阻塞OS线程 不阻塞载体线程
适用场景 CPU密集型任务 I/O密集型任务
虚拟线程实战示例:
public class VirtualThreadExample {
    public static void main(String[] args) throws Exception {
        System.out.println("=== Java 21 虚拟线程示例 ===");
        
        basicVirtualThread();
        virtualThreadExecutor();
        performanceComparison();
    }
    
    private static void basicVirtualThread() throws InterruptedException {
        System.out.println("\n--- 基本虚拟线程 ---");
        
        Thread virtualThread = Thread.ofVirtual()
            .name("virtual-worker")
            .start(() -> {
                System.out.println("虚拟线程: " + Thread.currentThread());
                System.out.println("是否为虚拟线程: " + Thread.currentThread().isVirtual());
                System.out.println("线程名称: " + Thread.currentThread().getName());
                
                try {
                    Thread.sleep(Duration.ofMillis(500));
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                System.out.println("虚拟线程完成任务");
            });
        
        virtualThread.join();
    }
    
    private static void virtualThreadExecutor() throws Exception {
        System.out.println("\n--- 虚拟线程执行器 ---");
        
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            List> futures = new ArrayList<>();
            
            for (int i = 0; i < 5; i++) {
                final int taskId = i;
                Future future = executor.submit(() -> {
                    System.out.printf("任务 %d 在线程: %s%n", taskId, Thread.currentThread().getName());
                    
                    try {
                        Thread.sleep(Duration.ofMillis(100 * (taskId + 1)));
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return "任务被中断";
                    }
                    
                    return "任务 " + taskId + " 完成";
                });
                futures.add(future);
            }
            
            for (Future future : futures) {
                System.out.println("结果: " + future.get());
            }
        }
    }
    
    private static void performanceComparison() {
        System.out.println("\n--- 性能对比测试 ---");
        
        int taskCount = 1000;
        
        long virtualThreadTime = measureTime(() -> {
            try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
                for (int i = 0; i < taskCount; i++) {
                    executor.submit(() -> {
                        try {
                            Thread.sleep(Duration.ofMillis(1));
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    });
                }
            }
        });
        
        System.out.printf("虚拟线程执行时间: %d ms%n", virtualThreadTime);
        System.out.printf("性能提升显著!%n");
    }
    
    private static long measureTime(Runnable task) {
        long start = System.currentTimeMillis();
        task.run();
        return System.currentTimeMillis() - start;
    }
}

虚拟线程使用注意事项

  • 避免在虚拟线程中使用synchronized关键字,推荐使用ReentrantLock
  • 不要池化虚拟线程,它们的创建成本很低
  • 虚拟线程适合I/O密集型任务,不适合CPU密集型任务
  • 某些阻塞操作可能会固定(pin)虚拟线程到载体线程

模式匹配增强

Java 21进一步增强了模式匹配功能,使得switch表达式更加强大和灵活。

模式匹配完整示例:
public class PatternMatchingExample {
    public static void main(String[] args) {
        System.out.println("=== Java 21 模式匹配增强示例 ===");
        
        basicPatternMatching();
        recordPatternMatching();
        guardedPatterns();
        nestedPatterns();
    }
    
    private static void basicPatternMatching() {
        System.out.println("\n--- 基本模式匹配 ---");
        
        Object[] testObjects = {"Hello", 42, 3.14, null, new StringBuilder("Builder")};
        
        for (Object obj : testObjects) {
            String result = switch (obj) {
                case String s -> "字符串: " + s + " (长度: " + s.length() + ")";
                case Integer i -> "整数: " + i + " (" + (i > 0 ? "正数" : i < 0 ? "负数" : "零") + ")";
                case Double d -> "浮点数: " + d;
                case null -> "空值";
                default -> "其他类型: " + obj.getClass().getSimpleName();
            };
            System.out.println(result);
        }
    }
    
    private static void recordPatternMatching() {
        System.out.println("\n--- 记录模式匹配 ---");
        
        record Point(int x, int y) {}
        record Circle(Point center, int radius) {}
        record Rectangle(Point topLeft, Point bottomRight) {}
        
        Object[] shapes = {
            new Circle(new Point(0, 0), 5),
            new Rectangle(new Point(1, 1), new Point(10, 10)),
            new Point(3, 4)
        };
        
        for (Object shape : shapes) {
            String description = switch (shape) {
                case Circle(Point(var x, var y), var r) -> 
                    String.format("圆: 圆心(%d,%d), 半径%d, 面积%.2f", x, y, r, Math.PI * r * r);
                case Rectangle(Point(var x1, var y1), Point(var x2, var y2)) -> {
                    int width = Math.abs(x2 - x1);
                    int height = Math.abs(y2 - y1);
                    yield String.format("矩形: 从(%d,%d)到(%d,%d), 面积%d", x1, y1, x2, y2, width * height);
                }
                case Point(var x, var y) -> String.format("点: (%d,%d)", x, y);
                default -> "未知形状";
            };
            System.out.println(description);
        }
    }
    
    private static void guardedPatterns() {
        System.out.println("\n--- 守卫模式 ---");
        
        Object[] values = {"Java", "Python", "C++", 100, -50, 0};
        
        for (Object value : values) {
            String category = switch (value) {
                case String s when s.length() > 4 -> "长编程语言名: " + s;
                case String s -> "短编程语言名: " + s;
                case Integer i when i > 50 -> "大整数: " + i;
                case Integer i when i < 0 -> "负整数: " + i;
                case Integer i -> "小非负整数: " + i;
                default -> "其他类型";
            };
            System.out.println(category);
        }
    }
    
    private static void nestedPatterns() {
        System.out.println("\n--- 嵌套模式匹配 ---");
        
        record Person(String name, int age) {}
        record Employee(Person person, String department, double salary) {}
        record Manager(Employee employee, int teamSize) {}
        
        Object[] workers = {
            new Employee(new Person("张三", 28), "开发部", 12000),
            new Manager(new Employee(new Person("李四", 35), "技术部", 18000), 8),
            new Person("王五", 22)
        };
        
        for (Object worker : workers) {
            String info = switch (worker) {
                case Manager(Employee(Person(var name, var age), var dept, var salary), var teamSize) 
                    when salary > 15000 -> 
                    String.format("高级经理 %s: %d岁, %s, 薪资%.0f, 管理%d人团队", name, age, dept, salary, teamSize);
                case Manager(Employee(Person(var name, var age), var dept, var salary), var teamSize) -> 
                    String.format("经理 %s: %d岁, %s, 薪资%.0f, 管理%d人团队", name, age, dept, salary, teamSize);
                case Employee(Person(var name, var age), var dept, var salary) when age < 30 -> 
                    String.format("年轻员工 %s: %d岁, %s, 薪资%.0f", name, age, dept, salary);
                case Employee(Person(var name, var age), var dept, var salary) -> 
                    String.format("资深员工 %s: %d岁, %s, 薪资%.0f", name, age, dept, salary);
                case Person(var name, var age) -> 
                    String.format("普通人员 %s: %d岁", name, age);
                default -> "未知人员类型";
            };
            System.out.println(info);
        }
    }
}

字符串模板(预览特性)

字符串模板是Java 21引入的预览特性,提供了类型安全的字符串插值功能。

预览特性说明

字符串模板是预览特性,需要使用 --enable-preview 标志来启用。在生产环境中使用前请谨慎考虑。

字符串模板示例:
public class StringTemplateExample {
    public static void main(String[] args) {
        System.out.println("=== Java 21 字符串模板示例 ===");
        
        basicStringTemplates();
        expressionTemplates();
        multiLineTemplates();
        formattedTemplates();
        customProcessor();
    }
    
    private static void basicStringTemplates() {
        System.out.println("\n--- 基本字符串模板 ---");
        
        String name = "Java";
        int version = 21;
        String feature = "字符串模板";
        
        // 使用STR模板处理器
        String message = STR."欢迎使用 \{name} \{version} 的新特性:\{feature}!";
        System.out.println(message);
        
        // 变量替换
        String language = "Java";
        String developer = "Oracle";
        String info = STR."\{language} 是由 \{developer} 开发的编程语言";
        System.out.println(info);
    }
    
    private static void expressionTemplates() {
        System.out.println("\n--- 表达式模板 ---");
        
        double price = 99.99;
        int quantity = 3;
        double discount = 0.1;
        
        // 计算表达式
        String invoice = STR."商品单价: \{price}元, 数量: \{quantity}个";
        System.out.println(invoice);
        
        String total = STR."小计: \{price * quantity}元";
        System.out.println(total);
        
        String finalPrice = STR."折扣后总价: \{(price * quantity) * (1 - discount)}元";
        System.out.println(finalPrice);
        
        // 方法调用
        String timeInfo = STR."当前时间: \{java.time.LocalDateTime.now()}";
        System.out.println(timeInfo);
    }
    
    private static void multiLineTemplates() {
        System.out.println("\n--- 多行字符串模板 ---");
        
        String productName = "Java 21 教程";
        String author = "小傅哥";
        double rating = 4.8;
        int reviews = 1250;
        
        String report = STR."""
            ╔══════════════════════════════════════╗
            ║              产品信息报告              ║
            ╠══════════════════════════════════════╣
            ║ 产品名称: \{productName}                ║
            ║ 作者: \{author}                        ║
            ║ 评分: \{rating}/5.0                    ║
            ║ 评论数: \{reviews}                     ║
            ║ 推荐指数: \{rating > 4.5 ? "⭐⭐⭐⭐⭐" : "⭐⭐⭐⭐"} ║
            ╚══════════════════════════════════════╝
            """;
        System.out.println(report);
    }
    
    private static void formattedTemplates() {
        System.out.println("\n--- 格式化模板 ---");
        
        double pi = Math.PI;
        int number = 42;
        String text = "Hello";
        
        // 使用FMT进行格式化
        String formatted1 = FMT."π的值: %.4f\{pi}";
        System.out.println(formatted1);
        
        String formatted2 = FMT."数字: %08d\{number}";
        System.out.println(formatted2);
        
        String formatted3 = FMT."文本: %10s\{text}";
        System.out.println(formatted3);
        
        // 组合格式化
        String combined = FMT."结果: %s\{text} - %d\{number} - %.2f\{pi}";
        System.out.println(combined);
    }
    
    private static void customProcessor() {
        System.out.println("\n--- 自定义模板处理器 ---");
        
        String greeting = "hello";
        String target = "world";
        String message = "java";
        
        // 使用自定义的大写处理器
        String upperResult = UPPER."\{greeting} \{target}! Welcome to \{message}";
        System.out.println("大写处理器结果: " + upperResult);
        
        // 使用自定义的JSON处理器
        String name = "张三";
        int age = 25;
        String city = "北京";
        
        String jsonResult = JSON."\{name}, \{age}, \{city}";
        System.out.println("JSON处理器结果: " + jsonResult);
    }
    
    // 自定义大写模板处理器
    public static final StringTemplate.Processor UPPER = 
        StringTemplate.Processor.of((StringTemplate st) -> {
            StringBuilder sb = new StringBuilder();
            Iterator fragments = st.fragments().iterator();
            Iterator values = st.values().iterator();
            
            while (fragments.hasNext()) {
                sb.append(fragments.next());
                if (values.hasNext()) {
                    sb.append(String.valueOf(values.next()).toUpperCase());
                }
            }
            return sb.toString();
        });
    
    // 自定义JSON模板处理器
    public static final StringTemplate.Processor JSON = 
        StringTemplate.Processor.of((StringTemplate st) -> {
            StringBuilder json = new StringBuilder("{");
            List fragments = st.fragments();
            List values = st.values();
            
            for (int i = 0; i < values.size(); i++) {
                if (i > 0) json.append(", ");
                
                String key = fragments.get(i).trim();
                if (key.endsWith(", ")) {
                    key = key.substring(0, key.length() - 2);
                }
                
                Object value = values.get(i);
                json.append('"').append(key.isEmpty() ? "value" + i : key).append('"');
                json.append(": ");
                
                if (value instanceof String) {
                    json.append('"').append(value).append('"');
                } else {
                    json.append(value);
                }
            }
            
            json.append("}");
            return json.toString();
        });
}
            
        

        
        

序列化集合

Java 21引入了序列化集合接口,为有序集合提供了统一的API,包括首尾元素的操作方法。

序列化集合完整示例:
import java.util.*;

public class SequencedCollectionsExample {
    public static void main(String[] args) {
        System.out.println("=== Java 21 序列化集合示例 ===");
        
        demonstrateSequencedList();
        demonstrateSequencedSet();
        demonstrateSequencedMap();
        practicalExamples();
    }
    
    private static void demonstrateSequencedList() {
        System.out.println("\n--- SequencedList 示例 ---");
        
        List list = new ArrayList<>();
        
        // 添加元素到首尾
        list.addFirst("开始");
        list.addLast("结束");
        list.add(1, "中间");
        
        System.out.println("列表内容: " + list);
        
        // 获取首尾元素
        System.out.println("第一个元素: " + list.getFirst());
        System.out.println("最后一个元素: " + list.getLast());
        
        // 反向视图
        List reversed = list.reversed();
        System.out.println("反向视图: " + reversed);
        
        // 移除首尾元素
        String removedFirst = list.removeFirst();
        String removedLast = list.removeLast();
        
        System.out.println("移除的第一个: " + removedFirst);
        System.out.println("移除的最后一个: " + removedLast);
        System.out.println("剩余内容: " + list);
    }
    
    private static void demonstrateSequencedSet() {
        System.out.println("\n--- SequencedSet 示例 ---");
        
        SequencedSet set = new LinkedHashSet<>();
        
        // 添加元素
        set.addFirst(1);
        set.addLast(3);
        set.add(2);
        set.addFirst(0);
        
        System.out.println("集合内容: " + set);
        
        // 获取首尾元素
        System.out.println("第一个元素: " + set.getFirst());
        System.out.println("最后一个元素: " + set.getLast());
        
        // 反向视图
        SequencedSet reversedSet = set.reversed();
        System.out.println("反向集合: " + reversedSet);
        
        // 移除首尾元素
        Integer removedFirst = set.removeFirst();
        Integer removedLast = set.removeLast();
        
        System.out.println("移除的第一个: " + removedFirst);
        System.out.println("移除的最后一个: " + removedLast);
        System.out.println("剩余集合: " + set);
    }
    
    private static void demonstrateSequencedMap() {
        System.out.println("\n--- SequencedMap 示例 ---");
        
        SequencedMap map = new LinkedHashMap<>();
        
        // 添加键值对
        map.put("second", "第二个");
        map.put("third", "第三个");
        map.putFirst("first", "第一个");
        map.putLast("fourth", "第四个");
        
        System.out.println("映射内容: " + map);
        
        // 获取首尾条目
        System.out.println("第一个条目: " + map.firstEntry());
        System.out.println("最后一个条目: " + map.lastEntry());
        
        // 反向视图
        SequencedMap reversedMap = map.reversed();
        System.out.println("反向映射: " + reversedMap);
        
        // 序列化键和值的视图
        System.out.println("序列化键: " + map.sequencedKeySet());
        System.out.println("序列化值: " + map.sequencedValues());
        System.out.println("序列化条目: " + map.sequencedEntrySet());
    }
    
    private static void practicalExamples() {
        System.out.println("\n--- 实际应用示例 ---");
        
        // 示例1: 最近访问的页面
        recentPagesExample();
        
        // 示例2: 任务队列
        taskQueueExample();
        
        // 示例3: 缓存实现
        cacheExample();
    }
    
    private static void recentPagesExample() {
        System.out.println("\n最近访问页面管理:");
        
        List recentPages = new ArrayList<>();
        int maxPages = 5;
        
        String[] visitedPages = {"首页", "产品页", "关于我们", "联系我们", "帮助页面", "用户中心"};
        
        for (String page : visitedPages) {
            // 如果页面已存在,先移除
            recentPages.remove(page);
            
            // 添加到最前面
            recentPages.addFirst(page);
            
            // 保持最大数量
            if (recentPages.size() > maxPages) {
                recentPages.removeLast();
            }
            
            System.out.println("访问 " + page + " 后的最近页面: " + recentPages);
        }
    }
    
    private static void taskQueueExample() {
        System.out.println("\n任务队列管理:");
        
        List taskQueue = new ArrayList<>();
        
        // 添加普通任务到队尾
        taskQueue.addLast("普通任务1");
        taskQueue.addLast("普通任务2");
        
        // 添加紧急任务到队首
        taskQueue.addFirst("紧急任务1");
        taskQueue.addFirst("紧急任务2");
        
        System.out.println("任务队列: " + taskQueue);
        
        // 处理任务(从队首开始)
        while (!taskQueue.isEmpty()) {
            String task = taskQueue.removeFirst();
            System.out.println("正在处理: " + task + ", 剩余任务: " + taskQueue);
        }
    }
    
    private static void cacheExample() {
        System.out.println("\nLRU缓存实现:");
        
        SequencedMap cache = new LinkedHashMap<>();
        int maxSize = 3;
        
        String[] operations = {"get:A", "put:A:值A", "put:B:值B", "get:A", "put:C:值C", "put:D:值D"};
        
        for (String op : operations) {
            String[] parts = op.split(":");
            String operation = parts[0];
            String key = parts[1];
            
            if ("get".equals(operation)) {
                String value = cache.get(key);
                if (value != null) {
                    // 移动到最后(最近使用)
                    cache.remove(key);
                    cache.putLast(key, value);
                    System.out.println("获取 " + key + ": " + value);
                } else {
                    System.out.println("获取 " + key + ": 未找到");
                }
            } else if ("put".equals(operation)) {
                String value = parts[2];
                
                // 如果已存在,先移除
                cache.remove(key);
                
                // 添加到最后
                cache.putLast(key, value);
                
                // 检查大小限制
                if (cache.size() > maxSize) {
                    Map.Entry oldest = cache.pollFirstEntry();
                    System.out.println("缓存已满,移除最旧的: " + oldest.getKey());
                }
                
                System.out.println("存储 " + key + ": " + value);
            }
            
            System.out.println("当前缓存: " + cache);
        }
    }
}
LinkedHashSet set = new LinkedHashSet<>(); // 添加元素 set.addFirst(1); set.addLast(3); set.add(2); System.out.println("集合内容: " + set); // 获取首尾元素 System.out.println("第一个元素: " + set.getFirst()); System.out.println("最后一个元素: " + set.getLast()); // 反向视图 SequencedSet reversed = set.reversed(); System.out.println("反向视图: " + reversed); // 在反向视图中添加元素 reversed.addFirst(4); // 实际上添加到原集合的末尾 System.out.println("添加后的原集合: " + set); } // SequencedMap示例 public static void demonstrateSequencedMap() { System.out.println("\n=== SequencedMap示例 ==="); LinkedHashMap map = new LinkedHashMap<>(); // 添加键值对到首尾 map.putFirst("first", 1); map.putLast("last", 100); map.put("middle", 50); System.out.println("映射内容: " + map); // 获取首尾条目 Map.Entry firstEntry = map.firstEntry(); Map.Entry lastEntry = map.lastEntry(); System.out.println("第一个条目: " + firstEntry); System.out.println("最后一个条目: " + lastEntry); // 移除首尾条目 Map.Entry removedFirst = map.pollFirstEntry(); Map.Entry removedLast = map.pollLastEntry(); System.out.println("移除的第一个: " + removedFirst); System.out.println("移除的最后一个: " + removedLast); System.out.println("剩余内容: " + map); // 反向视图 SequencedMap reversed = map.reversed(); System.out.println("反向视图: " + reversed); // 反向视图的键和值 System.out.println("反向键集: " + reversed.sequencedKeySet()); System.out.println("反向值集: " + reversed.sequencedValues()); } }

性能改进和其他特性

主要性能改进

内存管理优化

  • 改进的垃圾收集器性能
  • 更好的内存分配策略
  • 减少内存碎片
  • 优化的对象布局

启动时间优化

  • 更快的类加载
  • 改进的JIT编译
  • 优化的启动序列
  • 减少冷启动时间

运行时优化

  • 更好的分支预测
  • 优化的循环展开
  • 改进的内联策略
  • 更高效的异常处理

安全性增强

  • 更强的加密算法支持
  • 改进的安全管理器
  • 更好的证书验证
  • 增强的随机数生成

其他重要特性

其他新特性示例:
// 1. 改进的switch表达式
public class OtherFeaturesExample {
    
    // Key Encapsulation Mechanism API
    public static void demonstrateKEM() {
        try {
            // 生成密钥对
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("X25519");
            KeyPair keyPair = kpg.generateKeyPair();
            
            // 使用KEM API
            KEM kem = KEM.getInstance("DHKEM");
            KEM.Encapsulator encapsulator = kem.newEncapsulator(keyPair.getPublic());
            KEM.Encapsulated encapsulated = encapsulator.encapsulate();
            
            System.out.println("密钥封装完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    // 改进的Math类方法
    public static void demonstrateMathImprovements() {
        // 新的数学方法
        long result1 = Math.clamp(15, 10, 20); // 结果: 15
        long result2 = Math.clamp(5, 10, 20);  // 结果: 10
        long result3 = Math.clamp(25, 10, 20); // 结果: 20
        
        System.out.println("Clamp结果: " + result1 + ", " + result2 + ", " + result3);
    }
    
    // 改进的StringBuilder和StringBuffer
    public static void demonstrateStringBuilderImprovements() {
        StringBuilder sb = new StringBuilder();
        
        // 新的repeat方法
        sb.repeat("Hello ", 3);
        System.out.println(sb.toString()); // "Hello Hello Hello "
        
        // 改进的性能
        sb.setLength(0);
        for (int i = 0; i < 1000; i++) {
            sb.append("item").append(i).append(" ");
        }
        System.out.println("StringBuilder性能测试完成");
    }
}

迁移到Java 21

迁移建议

Java 21作为LTS版本,提供了良好的向后兼容性。大多数Java 8、11、17应用程序可以直接在Java 21上运行。

迁移检查清单

迁移步骤:
// 1. 检查依赖兼容性
// 确保所有第三方库支持Java 21

// 2. 更新构建配置
// Maven pom.xml

    21
    21


// Gradle build.gradle
java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

// 3. 启用预览特性(如果需要)
// javac --enable-preview --release 21 *.java
// java --enable-preview MyClass

// 4. 性能测试
// 在生产环境部署前进行充分的性能测试

// 5. 逐步采用新特性
// 优先使用虚拟线程改进并发性能
// 使用序列化集合简化代码
// 考虑使用模式匹配提高代码可读性

本章总结

  • Java 21是重要的LTS版本,引入了多项革命性特性
  • 虚拟线程极大简化了并发编程,适合I/O密集型应用
  • 模式匹配增强让代码更简洁、类型更安全
  • 字符串模板提供了类型安全的字符串插值功能
  • 序列化集合统一了有序集合的API设计
  • 性能改进涵盖内存管理、启动时间和运行时优化
  • 迁移到Java 21具有良好的向后兼容性