文章目录
- [1 开发者可见特性(直接影响编码)](#1 开发者可见特性(直接影响编码))
-
- [1.1 局部变量类型推断(var)](#1.1 局部变量类型推断(var))
- [1.2 新增 API 改进](#1.2 新增 API 改进)
-
- [1.2.1 集合的 `copyOf` 方法](#1.2.1 集合的
copyOf方法) - [1.2.2 `Reader.transferTo` 方法](#1.2.2
Reader.transferTo方法) - [1.2.3 IO流支持 `Charset` 参数](#1.2.3 IO流支持
Charset参数) - [1.2.4 `ByteArrayOutputStream.toString(Charset)`](#1.2.4
ByteArrayOutputStream.toString(Charset))
- [1.2.1 集合的 `copyOf` 方法](#1.2.1 集合的
- [2 JVM 与性能优化特性(开发者不可直接使用)](#2 JVM 与性能优化特性(开发者不可直接使用))
-
- [2.1 垃圾收集器接口(JEP 304)](#2.1 垃圾收集器接口(JEP 304))
- [2.2. G1 引入并行 Full GC(JEP 307)](#2.2. G1 引入并行 Full GC(JEP 307))
- [2.3 应用程序类数据共享(AppCDS)(JEP 310)](#2.3 应用程序类数据共享(AppCDS)(JEP 310))
- [2.4 线程本地握手(Thread-Local Handshakes)(JEP 312)](#2.4 线程本地握手(Thread-Local Handshakes)(JEP 312))
- [2.5 在备用存储装置上的堆分配(JEP 316)](#2.5 在备用存储装置上的堆分配(JEP 316))
- [2.6. 基于 Java 的实验性 JIT 编译器(Graal)(JEP 317)](#2.6. 基于 Java 的实验性 JIT 编译器(Graal)(JEP 317))
- [3 平台与维护特性](#3 平台与维护特性)
-
- [3.1 删除 `javah` 工具(JEP 313)](#3.1 删除
javah工具(JEP 313)) - [3.2 Unicode 语言标签扩展(JEP 314)](#3.2 Unicode 语言标签扩展(JEP 314))
- [3.3 根证书(JEP 319)](#3.3 根证书(JEP 319))
- [3.4 基于时间的发行版本控制(JEP 322)](#3.4 基于时间的发行版本控制(JEP 322))
- [3.1 删除 `javah` 工具(JEP 313)](#3.1 删除
- [4 内部维护特性](#4 内部维护特性)
-
- [4.1 合并 JDK 多个代码仓库(JEP 296)](#4.1 合并 JDK 多个代码仓库(JEP 296))
1 开发者可见特性(直接影响编码)
1.1 局部变量类型推断(var)
- 使用
var关键字进行局部变量类型推断,减少样板代码 - 编译器根据右侧表达式自动推断类型
java
// JDK 10之前
String str = "abc";
ArrayList<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
// JDK 10之后
var str = "abc"; // 推断为 String
var list = new ArrayList<String>(); // 推断为 ArrayList<String>
var stream = list.stream(); // 推断为 Stream<String>
使用限制:
| 场景 | 是否可用 | 示例 |
|---|---|---|
| 局部变量 | ✅ | var x = 10; |
| for循环变量 | ✅ | for (var s : list) |
| 成员变量 | ❌ | var x = 10; // 类字段不行 |
| 方法参数 | ❌ | void test(var a) |
| 方法返回类型 | ❌ | var test() { return 1; } |
| 未初始化变量 | ❌ | var x; x = 10; |
| 多个变量声明 | ❌ | var a=1, b=2; |
其他:
var不是关键字,是保留类型名,可以用作标识符(但不推荐)- 编译后字节码中仍保留具体类型,不影响性能
- 与JavaScript的
var完全不同,Java的var仍是强类型
1.2 新增 API 改进
1.2.1 集合的 copyOf 方法
java
var list = new ArrayList<String>();
list.add("aa");
var list2 = List.copyOf(list); // 返回不可变集合
list2.add("bb"); // 抛出 UnsupportedOperationException
- 返回的是
ImmutableCollections.ListN(内部不可变实现) - 适用于
List、Set、Map
1.2.2 Reader.transferTo 方法
java
// 以前需要手动循环读写
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) != -1) {
writer.write(buffer, 0, len);
}
// JDK 10 一行搞定
reader.transferTo(writer);
- 内部实现仍是循环读写,但代码更简洁
- 返回实际传输的字符数(
long类型)
1.2.3 IO流支持 Charset 参数
java
// 指定编码创建打印流
var ps = new PrintStream("output.txt", Charset.forName("GBK"));
var scanner = new Scanner(file, Charset.forName("UTF-8"));
- 影响的类:
PrintStream、PrintWriter、Scanner
1.2.4 ByteArrayOutputStream.toString(Charset)
java
var bos = new ByteArrayOutputStream();
// ... 写入数据
String str = bos.toString(StandardCharsets.UTF_8); // 指定编码转字符串
2 JVM 与性能优化特性(开发者不可直接使用)
2.1 垃圾收集器接口(JEP 304)
- 引入干净的 GC 接口,改善不同垃圾回收器的源代码隔离
- 方便在 JVM 中添加或移除 GC 实现
- 内部重构,将 GC 代码从
gc/shared等目录模块化 - 为后续引入新 GC(如 ZGC、Shenandoah)奠定基础
- 不影响 GC 调优参数的使用方式

2.2. G1 引入并行 Full GC(JEP 307)
- JDK 9 默认使用 G1,但 Full GC 是单线程
- JDK 10 将 Full GC 改为并行算法,减少停顿时间
- G1 设计目标是低延迟,但单线程 Full GC 是性能瓶颈
- 并行 Full GC 使用多线程回收,显著提升大内存场景下的 Full GC 性能
- 可通过
-XX:ParallelGCThreads控制线程数
2.3 应用程序类数据共享(AppCDS)(JEP 310)
- 扩展 JDK 5 引入的 CDS,允许应用类加载器、平台类加载器加载归档类
- 减少启动时间和内存占用
- 使用流程:
- 训练阶段:
-XX:DumpLoadedClassList=classes.list记录加载的类 - 归档阶段:
-Xshare:dump生成共享归档文件(.jsa) - 运行阶段:
-Xshare:on -XX:SharedArchiveFile=app.jsa使用归档
- 训练阶段:
- 特别适合容器化部署(多个 JVM 共享同一镜像的类数据)
2.4 线程本地握手(Thread-Local Handshakes)(JEP 312)
- 修改 Safepoint 机制,允许单个线程回调,无需停止所有线程
- 更"温和"的线程管控方式
- Safepoint 问题: 传统方式需要所有线程到达安全点才能执行 GC、偏向锁撤销等操作
- 优化效果: 某些操作(如线程栈采样)只需暂停目标线程,不影响其他线程执行
- 为后续低延迟特性(如 ZGC 的并发标记)提供技术基础
2.5 在备用存储装置上的堆分配(JEP 316)
- 支持将 Java 堆分配在 NV-DIMM 等非易失性内存上
- 无需修改应用程序代码
- NV-DIMM 特点: 比 DRAM 便宜、容量大、断电数据不丢失,但速度较慢
- 适用场景:
- 多 JVM 部署中低优先级进程(守护进程)使用 NV-DIMM,高优先级进程使用 DRAM
- 大数据、内存数据库等需要大内存堆的应用
- JVM 参数:
-XX:AllocateHeapAt=<path>指定存储路径
2.6. 基于 Java 的实验性 JIT 编译器(Graal)(JEP 317)
- 将 Graal 编译器(用 Java 编写)引入 JDK
- 目标:让 JIT 编译器性能匹敌或超越 C++ 版本
- 背景: HotSpot 的 C2 编译器用 C++ 编写,难以维护和优化
- Graal 优势:
- 用 Java 编写,更易开发和调试
- 支持提前编译(AOT),为 JDK 9 的
jaotc工具提供基础 - 更好的逃逸分析和内联优化
- 启用参数:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler - 注意: JDK 10 中是实验性特性,JDK 11+ 逐渐成熟
3 平台与维护特性
3.1 删除 javah 工具(JEP 313)
javah用于生成 JNI 头文件(.h)- 功能已集成到
javac -h中 - 迁移命令:
javah com.example.MyClass→javac -h . com/example/MyClass.java
3.2 Unicode 语言标签扩展(JEP 314)
之前对Unicode语言环境扩展仅限于日历和数字。该JEP在相关JDK类中实现最新规范中指定的更多扩展。
| 扩展 | 含义 | 示例 |
|---|---|---|
cu |
货币类型 | zh-CN-u-cu-USD(人民币显示美元) |
fw |
一周的第一天 | en-US-u-fw-mon(周一为周首) |
rg |
区域覆盖 | en-GB-u-rg-uszzzz(英式英语,美式区域) |
tz |
时区 | zh-CN-u-tz-uslax(洛杉矶时区) |
影响 API: DateFormat、NumberFormat、DateTimeFormatter、Currency、Locale 等
3.3 根证书(JEP 319)
- OpenJDK 之前密钥库为空,TLS 等安全组件默认不可用
- JDK 10 开源 Oracle Java SE Root CA 程序中的根证书
- 意义: 减少 OpenJDK 与 Oracle JDK 在安全性上的差异,提升 OpenJDK 可用性
3.4 基于时间的发行版本控制(JEP 322)
版本号格式变更:
旧格式(JDK 9):9.0.1 // 主版本.安全.补丁
新格式(JDK 10+):10 // 功能发布版本
10.0.1 // 更新发布(仅修复bug)
10.0.2
11 // 6个月后的下一个功能发布
- 发布节奏: 每 6 个月一个功能发布(3月和9月),每 3 年一个 LTS 版本
- 版本信息 API:
Runtime.version()返回Runtime.Version对象,包含主版本、次版本、安全级别、补丁号、构建号等
4 内部维护特性
4.1 合并 JDK 多个代码仓库(JEP 296)
- 将 JDK 9 分散的 8 个仓库(root、corba、hotspot、jaxp、jaxws、jdk、langtools、nashorn)合并为单一仓库
- 目的: 支持跨模块的原子提交(atomic commit),简化开发流程