Java 在 2025 年:哪些变化以及为何需要更新代码

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java 并未消亡——它正在重生

\n

每年都有人写“Java 已死”。而每年 Java 都证明了事实恰恰相反。在 2025 年,这个已有近 30 年历史的语言将迎来多项基础性更新。如果你还在用 Java 编程,但上一次查看更新日志是在一年前——那么你已经落后了。让我们来具体分析一下哪些内容会改变,以及这些改变将如何影响你的代码。

\n

我不会用枯燥的规范来烦你。相反,我会提供一些你(几乎)今天就能运行的实例。我们开始吧。

\n\n

虚拟线程(Project Loom)——阻塞时代的终结

\n

这可能是最引人注目的变化。虚拟线程(virtual threads)是一种轻量级线程,允许你以同步风格编写异步代码。在 2025 年,它们终于变得稳定并推荐用于生产环境。

\n

以前,你可能会写类似这样的代码:

\n
ExecutorService executor = Executors.newFixedThreadPool(10);\nexecutor.submit(() -> {\n    // 阻塞调用\n    String result = restTemplate.getForObject(url, String.class);\n    return result;\n});
\n

问题在于,每个线程都是一个重量级对象。10 个线程没问题,10,000 个就会出问题。使用虚拟线程,你可以启动数百万个线程而无需担心内存:

\n
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {\n    for (int i = 0; i < 100_000; i++) {\n        executor.submit(() -> {\n            // 现在这是轻量级的\n            String result = restTemplate.getForObject(url, String.class);\n            return result;\n        });\n    }\n}
\n

关键区别在于:虚拟线程不绑定到操作系统线程。当线程阻塞时(例如在 I/O 上),JVM 只需将其切换到另一个虚拟线程。没有任何额外开销。

\n

这对你意味着什么?忘掉像 CompletableFuture 和响应式库这样复杂的异步框架吧。在 2025 年,基于虚拟线程的标准同步代码将既更快又更简单。

\n\n

如何迁移

\n

将 newFixedThreadPool 替换为 newVirtualThreadPerTaskExecutor。如果你使用 Spring Boot,请更新到 3.2+ 版本,那里已经提供了支持。只需确保你的库在关键部分没有使用 synchronized——这是虚拟线程可能“卡住”的唯一情况。

\n\n

模式匹配与 Switch——代码变得更简洁

\n

在 2025 年,模式匹配已经扩展到 switch 和 instanceof。现在,你可以编写简洁且可读的代码,而不是一堆嵌套的 if-else。

\n

以前(旧风格):

\n
if (obj instanceof String) {\n    String s = (String) obj;\n    System.out.println(s.length());\n} else if (obj instanceof Integer) {\n    Integer i = (Integer) obj;\n    System.out.println(i * 2);\n}
\n

现在(Java 21+):

\n
switch (obj) {\n    case String s -> System.out.println(s.length());\n    case Integer i -> System.out.println(i * 2);\n    case null -> System.out.println("null");\n    default -> System.out.println("unknown");\n}
\n

请注意 case null——这是一项单独的改进。以前,switch 在传入 null 时会抛出 NullPointerException。现在你可以显式地处理它。

\n

另一个很酷的功能是 记录模式(record patterns)。如果你有一个 record:

\n
record Point(int x, int y) {}
\n

那么你可以这样写:

\n
if (obj instanceof Point(int x, int y)) {\n    System.out.println("x=" + x + ", y=" + y);\n}
\n

无需多余的强制类型转换。在 2025 年,这将成为主流——使用它来使代码更整洁。

\n\n

垃圾回收:ZGC 和分代 GC

\n

在 2025 年,垃圾回收变得更快。ZGC(Z Garbage Collector)现在默认用于大多数应用程序。它的

博客

书籍推荐