从JDK 1.8到JDK 21:实用新特性

下方所有代码示例均可直接在JDK 21环境下运行。

一、语法精简:编写更优雅的代码

1. 局部变量类型推断 (JDK 10+)

解决痛点:冗长的泛型声明,代码可读性差

java 复制代码
// JDK 8
Map<String, List<Map<String, Object>>> complexMap = new HashMap<>();

// JDK 10+:使用var简化
var complexMap = new HashMap<String, List<Map<String, Object>>>();

使用规则

  • 仅适用于局部变量(方法内部)
  • 不能用于方法参数、返回类型或字段
  • 初始化时必须赋值
  • 保持代码可读性,不滥用

2. 文本块 (JDK 15正式版)

解决痛点:多行字符串拼接混乱,JSON/XML/SQL等格式难以维护

java 复制代码
// JDK 8
String json = "{\n" +
              "  \"name\": \"John\",\n" +
              "  \"age\": 30,\n" +
              "  \"city\": \"New York\"\n" +
              "}";

// JDK 15+:文本块
String json = """
              {
                "name": "John",
                "age": 30,
                "city": "New York"
              }
              """;

// SQL查询示例
String query = """
    SELECT u.id, u.name, o.order_id, o.amount
    FROM users u
    JOIN orders o ON u.id = o.user_id
    WHERE u.active = true
      AND o.created_date > ?
    ORDER BY o.created_date DESC
    LIMIT 10
    """;

// HTML模板
String title = "", userName = "", orderId = "";
String html = """
    <!DOCTYPE html>
    <html>
    <head>
        <title>%s</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>Welcome, %s!</h1>
        <p>Your order #%s has been processed.</p>
    </body>
    </html>
    """.formatted(title, userName, orderId);

// 保留格式的文本
String banner = """
                **************************
                *   APPLICATION STARTED  *
                *   Version: 2.3.1       *
                **************************
                """;
System.out.println(banner.strip());

3. 模式匹配 (JDK 16+)

解决痛点:繁琐的类型检查与转换

java 复制代码
public class ModeMatchUtil {
    public static void main(String[] args) {
        String s1 = formatterPatternSwitch(1);
        System.out.println(s1);

        String s2 = formatterPatternSwitch("1");
        System.out.println(s2);

        String s3 = formatterPatternSwitch(1L);
        System.out.println(s3);

        String s4 = formatterPatternSwitch(1.1);
        System.out.println(s4);

        // ------------------
        String j1 = jdk14("F");
        String j2 = jdk14("");
    }


    // JDK 16+:switch 模式匹配
    static String formatterPatternSwitch(Object obj) {
        return switch (obj) {
            case Integer i -> String.format("int %d", i);
            case Long l -> String.format("long %d", l);
            case Double d -> String.format("double %f", d);
            case String s -> String.format("String %s", s);
            default -> obj.toString();
        };
    }

    // JDK 16+:instanceOf模式匹配
    static void instanceOf(Object o) {
        if (o instanceof String s) {
            System.out.println(s);
        }
        if (o instanceof Integer s) {
            System.out.println(s);
        }
        if (o instanceof Long s) {
            System.out.println(s);
        }
    }

    static String jdk14(String day) {
        String result = switch (day) {
            case "M", "W", "F" -> "MWF";
            case "T", "TH", "S" -> "TTS";
            default -> {
                if(day.isEmpty())
                    yield "Please insert a valid day.";
                else
                    yield "Looks like a Sunday.";
            }

        };
        System.out.println(result);
        return result;
    }
}

二、集合与API增强:提升开发效率

1. 集合工厂方法 (JDK 9+)

解决痛点:不可变集合创建繁琐,易出错

java 复制代码
// JDK 8
List<String> names = Collections.unmodifiableList(Arrays.asList("Alice", "Bob", "Charlie"));
Set<String> roles = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("admin", "user")));
Map<String, Integer> scores = Collections.unmodifiableMap(new HashMap<String, Integer>() {{
    put("Alice", 95);
    put("Bob", 87);
}});

// JDK 9+:简洁、安全、高效
List<String> names = List.of("Alice", "Bob", "Charlie");
Set<String> roles = Set.of("admin", "user");
Map<String, Integer> scores = Map.of("Alice", 95, "Bob", 87);

// 较大的不可变映射
Map<String, String> config = Map.ofEntries(
    Map.entry("database.url", "jdbc:mysql://localhost:3306/mydb"),
    Map.entry("database.user", "admin"),
    Map.entry("database.password", "secret"),
    Map.entry("max.connections", "100"),
    Map.entry("timeout", "30000")
);
// 注意:这些集合是真正不可变的,尝试修改会抛出UnsupportedOperationException

2. Stream API增强 (JDK 9-21)

解决痛点:Stream处理复杂场景能力不足

java 复制代码
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 4, 3, 2, 1);

// filter: 保留所有满足条件的元素
List<Integer> filtered = numbers.stream()
        .filter(n -> n < 4)
        .toList();
// 结果: [1, 2, 3, 3, 2, 1] - 所有小于4的元素

// takeWhile: 从开头保留满足条件的连续元素,遇到第一个不满足的就停止
List<Integer> taken = numbers.stream()
        .takeWhile(n -> n < 4)
        .toList();
// 结果: [1, 2, 3] - 遇到4(不满足n<4)后停止

// dropWhile: 跳过开头满足条件的连续元素,从第一个不满足的开始保留
List<Integer> dropped = numbers.stream()
        .dropWhile(n -> n < 4)
        .toList();
// 结果: [4, 5, 4, 3, 2, 1] - 跳过1,2,3,从4开始保留所有

3. 新HTTP客户端 (JDK 11+)

解决痛点:旧HttpURLConnection API复杂,第三方依赖(如Apache HttpClient)增加项目负担

java 复制代码
// 同步GET请求
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
    .header("Accept", "application/json")
    .timeout(Duration.ofSeconds(10))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());

// 异步GET请求
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
future.thenApply(HttpResponse::body)
      .thenAccept(System.out::println)
      .join();

// POST JSON数据
String json = """
    {
      "title": "foo",
      "body": "bar",
      "userId": 1
    }
    """;

HttpRequest postRequest = HttpRequest.newBuilder()
    .uri(URI.create("https://jsonplaceholder.typicode.com/posts"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();

HttpResponse<String> postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString());
System.out.println("POST Response: " + postResponse.body());

三、并发与性能革命 (JDK 21)

1. 虚拟线程 (Project Loom) - JDK 21正式版

解决痛点:传统线程模型资源消耗大,高并发场景性能瓶颈

html 复制代码
// 传统线程池方式 (JDK 8)
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
    final int taskId = i;
    futures.add(executor.submit(() -> {
        // 模拟I/O操作
        Thread.sleep(1000);
        return "Task " + taskId + " completed";
    }));
}
// 需要处理大量Future,资源利用率低

// 虚拟线程方式 (JDK 21)
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
    List<String> results = IntStream.range(0, 10000)  // 10000个任务
        .mapToObj(i -> CompletableFuture.supplyAsync(() -> {
            // 模拟I/O密集型任务
            try {
                Thread.sleep(100);  // 模拟网络/数据库延迟
                return "Result from virtual thread " + i;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
        }, executor))
        .map(CompletableFuture::join)  // 等待所有任务完成
        .toList();
    
    System.out.println("Processed " + results.size() + " tasks");
}

性能对比

java 复制代码
public class VirtualThreadUtil {
    public static void main(String[] args) throws Exception {
        int taskCount = 10000;

        // 传统线程池
        ExecutorService traditional = Executors.newFixedThreadPool(200);
        testExecutor(traditional, taskCount, "Traditional Threads");

        // 虚拟线程
        try (ExecutorService virtual = Executors.newVirtualThreadPerTaskExecutor()) {
            testExecutor(virtual, taskCount, "Virtual Threads");
        }
    }

    private static void testExecutor(ExecutorService executor, int taskCount, String name) {
        long start = System.currentTimeMillis();

        List<CompletableFuture<Void>> futures = new ArrayList<>(taskCount);
        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            futures.add(CompletableFuture.runAsync(() -> {
                try {
                    Thread.sleep(100); // 模拟I/O等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }, executor));
        }

        futures.forEach(CompletableFuture::join);
        long end = System.currentTimeMillis();

        System.out.printf("%s: %d tasks completed in %dms%n",
                name, taskCount, (end - start));

        if (executor instanceof ThreadPoolExecutor pool) {
            System.out.printf("  Active threads: %d%n", pool.getActiveCount());
        }
    }
}

典型输出:

java 复制代码
Traditional Threads: 10000 tasks completed in 5280ms
  Active threads: 200
Virtual Threads: 10000 tasks completed in 1250ms
相关推荐
鱼跃鹰飞2 小时前
Leetcode1027:最长等差数列
java·数据结构·算法
2301_797312262 小时前
学习Java42天
java·开发语言·学习
chilavert3182 小时前
技术演进中的开发沉思-325 JVM:java体系技术全貌(下)
java·开发语言·jvm
chilavert3182 小时前
技术演进中的开发沉思-324 JVM:java技术体系全貌(上)
java·开发语言
pcm1235672 小时前
通信服务前沿知识
java
晓13132 小时前
第二章:Redis常见命令与Java客户端
java·数据库·redis
invicinble2 小时前
对于springboot
java·spring boot·后端
莫问前路漫漫2 小时前
JRE 核心实操指南:安装、配置、调优与问题排查
java·eclipse·tomcat·jre
填满你的记忆3 小时前
【从零开始——Redis 进化日志|Day7】双写一致性难题:数据库与缓存如何不再“打架”?(附 Canal/读写锁实战)
java·数据库·redis·缓存·面试