Java 11 - 现代平台的稳定基线
📑 Java 演进系列:总览 | Java 8 | Java 11 | Java 17 | Java 21 | Java 25
Java 11 于 2018-09-25 正式发布,是继 Java 8 之后的第一个长期支持(LTS)版本。它承接了 Java 9 的模块系统与 Java 10 的 var 局部变量推断——这些在中间非 LTS 版本定稿的特性在此 LTS 中可用,并为后续版本确立了半年一次的发布节奏。Java 11 的主线变化在平台与工具链:标准化 HTTP 客户端、单文件源码启动、JFR 开源,以及从 JDK 中移除 Java EE 与 CORBA 模块,使 Java 由"带 Java EE 的 JDK"收敛为更精简的现代平台基线。
HTTP 客户端
标准库内置的 java.net.http.HttpClient(JEP 321)取代了老旧的 HttpURLConnection——后者 API 设计于 2000 年前后,不支持异步、不可变性差、流式处理繁琐。新客户端原生支持 HTTP/2(通过 HTTP/1.1 协商升级)、WebSocket、同步与异步两种调用方式,且 HttpClient 与 HttpRequest 均为不可变对象,可安全共享。
同步调用 send 阻塞直至响应完成,适合简单脚本与后台任务;异步调用 sendAsync 返回 CompletableFuture,可直接与 Java 8 的组合式异步 API 衔接,且不占用平台线程等待网络。
1 | |
超时语义分两层:connectTimeout 限制建立连接的时间,请求级的 timeout 限制整个请求的完成时间,二者不可混淆。响应体通过 BodyHandlers 声明式处理——ofString、ofFile、ofInputStream 分别对应文本、落盘与流式消费。
Lambda 参数中的 var
Java 10 引入 var 局部变量推断(在此 LTS 中可用),Java 11 将其扩展到 lambda 参数(JEP 323)。表面上看 (var a, var b) -> a + b 与 (a, b) -> a + b 等价,前者的实际价值只有一个:允许为 lambda 参数附加注解。Java 语法规定参数注解必须依托显式类型,推断场景下 var 就是那个显式类型。
规则是"全有或全无":要么所有参数都声明 var,要么全部省略,混用即编译错误。
1 | |
日常代码中若无需注解,直接省略 var 即可;该特性主要服务于框架与校验工具在 lambda 参数上表达约束的场景。
字符串与文件 API
String 与 Files 补齐了一批高频小工具(JEP 331 与 JDK 11 API 更新),消除了此前依赖 Apache Commons 或手写循环的样板代码。字符串方面重点关注 Unicode 语义:strip 按 Unicode 空白定义裁剪,trim 只处理 ASCII 码位不大于 20 的字符,处理多语言文本时应优先 strip。
1 | |
文件方面,Files.readString 与 Files.writeString 把"读一个小文本文件"从 BufferedReader + try-with-resources 样板压缩为一行。两者均按 UTF-8 处理(可用带 Charset 的重载覆盖),适合配置、模板等小文件;大文件仍应使用流式 API。
1 | |
配套的还有 Path.of(取代 Paths.get,消除两套等价 API)与 Files.isSameFile 等增量改进,均属同一批易用性更新。
单文件源码启动
JEP 330 允许直接以源文件为入口启动程序:java Hello.java 在内存中编译后立即执行 main,不产生 .class 文件。这把 Java 的"写第一个程序"成本拉到与脚本语言同级——教学、工具原型、一次性维护脚本都不再需要 javac 与 classpath 布局。
1 | |
两个边界要清楚:其一,该模式按文件名而非类名定位源码,类名与文件名不必一致,但传入的必须是 .java 文件,否则 java Hello 仍被解释为运行已编译的 Hello 类;其二,它只做单文件编译,依赖第三方库时仍需构建工具,生产代码不因此放弃 javac/Maven/Gradle 流程。
安全性与可观测性
JDK Flight Recorder(JFR,JEP 328)在 Java 11 中开源并入 JDK。它以接近零开销的方式持续采集 JVM 与应用的运行事件(GC、锁竞争、方法采样、分配压力),配合 JDK Mission Control 分析,是生产环境性能诊断的首选工具——取代了此前需要商业授权的 Oracle JMC 生态。
1 | |
传输层方面,Java 11 提供 TLS 1.3 支持(JEP 319 的后继实现):握手往返更少、默认前向保密,SSLSocket 与新 HTTP 客户端均可协商使用。同一批运行时更新中,Epsilon 垃圾回收器(JEP 318,无操作 GC,用于性能基准与超短生命周期任务)与 ZGC(JEP 333,实验性低延迟 GC,暂停目标亚毫秒)也一并亮相——注意这两者是 HotSpot/JDK 的实现选择而非 Java SE 规范保证,其他 JDK 实现未必提供,且 ZGC 当时处于实验阶段,需 -XX:+UnlockExperimentalVMOptions 显式开启。
常用特性总结
- HTTP 客户端:
java.net.http.HttpClient支持 HTTP/2 与 WebSocket,send同步、sendAsync异步返回CompletableFuture。 var扩展:lambda 参数可声明var,全有或全无;为 lambda 参数附加注解的唯一途径。- 字符串方法:
isBlank判空白,strip按 Unicode 裁剪,repeat重复,lines按行流式处理。 - 文件读写:
Files.readString/Files.writeString一次性 UTF-8 文本读写,Path.of取代Paths.get。 - 单文件启动:
java Hello.java直接运行源文件,适合脚本与原型。 - JFR 开源:零开销生产级 profiling,
-XX:StartFlightRecording开箱即用。 - TLS 1.3:更快的握手与前向保密。
- 运行时选项(HotSpot/JDK):Epsilon 与实验性 ZGC 属实现选择,非 Java SE 保证。
迁移与兼容性
从 Java 8 升级到 Java 11 最大的断裂点是 Java EE 模块移除:java.xml.bind(JAXB)、java.xml.ws(JAX-WS)、java.activation、java.corba 与 java.transaction(仅 EE 部分)不再随 JDK 发行,需在构建中显式加入对应依赖(如 jakarta.xml.bind-api 及实现)。JavaFX 同样从 Oracle JDK 11 中剥离,改由 OpenJFX 单独发布。
其余迁移成本集中在工具链:Nashorn JavaScript 引擎在 11 中标记废弃;-source/-target 最低支持提升至 Java 7;此前版本默认的 --illegal-access 对内部 API 的宽容在 11 中仅剩一次警告机会,依赖 sun.misc.Unsafe 等内部 API 的库必须升级。实践中建议先在 CI 中以 --add-opens 临时放行定位问题,再推动依赖库升级消除警告;应用层 API(集合、流、var、HTTP 客户端)则完全向后兼容,可渐进采用。






