Java 10 于 2018年3月发布,这是 Java 采用新发布周期后的第一个版本。虽然特性不多,但引入了备受关注的 var 关键字,让 Java 代码可以更加简洁。
正式特性
【实用】局部变量类型推断(var)
用过弱类型编程语言的朋友应该知道,不用自己声明变量的类型有多爽。
但是对于 Java 这种强类型语言,我们经常要写下面这种代码,一个变量类型写老长(特别是在泛型场景下):
Map<String, List<Integer>> complexMap = new HashMap<String, List<Integer>>();
ArrayList<String> list = new ArrayList<String>();
Iterator<Map.Entry<String, List<Integer>>> iterator = complexMap.entrySet().iterator();好在 Java 10 引入了 var 关键字,支持局部变量的类型推断,编译器会根据初始化表达式自动推断变量的类型,让代码可以变得更简洁。
var complexMap = new HashMap<String, List<Integer>>();
var list = new ArrayList<String>();
var iterator = complexMap.entrySet().iterator();
// 使用 var 的 for-each 循环
for (var entry : complexMap.entrySet()) {
var key = entry.getKey();
var value = entry.getValue();
// 处理逻辑
}但是,var 关键字是一把双刃剑,不是所有程序员都喜欢它。毕竟代码中都是 var,丢失了一定的可读性,尤其是下面这种代码,你不能直观地了解变量的类型:
var data = getData();而且使用 var 时,还要确保编译器能正确推断类型,下面这几种写法都是错误的:

所以我个人其实是没那么喜欢用这个关键字的,纯个人偏好。
var 使用注意事项
只能用于局部变量:不能用于字段、方法参数或返回类型
必须初始化:声明时必须赋值,让编译器能推断类型
不能推断 null:
var x = null;是错误的不能推断泛型:
var list = new ArrayList<>();会推断为ArrayList<Object>
public class VarExample {
// var field = "错误"; // 不能用于字段
public void method() {
// 正确用法
var name = "张三"; // String
var age = 25; // int
var salary = 5000.5; // double
var isActive = true; // boolean
var list = List.of(1, 2, 3); // List<Integer>
// 错误用法
// var x; // 必须初始化
// var y = null; // 不能推断null
// var z = () -> {}; // 不能推断lambda
}
// public var getResult() { } // 不能用于返回类型
// public void process(var param) { } // 不能用于参数
}【了解】应用程序类数据共享
Java 10 扩展了类数据共享功能,允许应用程序类也参与共享(Application Class-Data Sharing)。在此之前,只有 JDK 核心类可以进行类数据共享,应用程序类每次启动都需要重新加载和解析。
类数据共享的核心思路是:将 JDK 核心类和应用程序类的元数据都打包到共享归档文件中,多个 JVM 实例同时映射同一个归档文件,通过 共享读取 优化应用启动时间和减少内存占用。

使用步骤:Ea7H6DxcZeWlVJFFEnFyn3Lx21/mLUEMxr9P/hnm5xs=
- 生成类列表:
java -XX:DumpLoadedClassList=classes.lst MyApp- 创建归档文件:
java -Xshare:dump -XX:SharedClassListFile=classes.lst -XX:SharedArchiveFile=myapp.jsa- 使用归档文件启动:
java -Xshare:on -XX:SharedArchiveFile=myapp.jsa MyApp这个特性主要用于容器化部署和微服务场景,可以显著减少启动时间。
【了解】垃圾收集器接口
Java 10 引入了统一的垃圾收集器接口,为不同的 GC 实现提供了标准化的框架。这个改进主要是为了:
简化新 GC 算法的开发和集成
提高代码的可维护性
支持更灵活的 GC 配置
这个特性对普通开发者来说是透明的,主要影响 JVM 内部实现。
【了解】G1 的并行完整 GC
在 Java 10 之前,G1 垃圾收集器的 Full GC 是单线程的,当堆内存不足时性能会很差。
Java 10 改进了 G1 的 Full GC 实现,使用并行算法:
# 启用 G1 垃圾收集器
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 MyApp并行 Full GC 可以显著减少长时间的停顿,提升应用的响应性。
【了解】线程局部握手
线程局部握手(Thread-Local Handshakes)是一个 JVM 内部优化,允许在不停止所有线程的情况下对单个线程执行回调:
减少全局安全点的使用
降低 JVM 操作的延迟
提高整体性能
这个特性对开发者透明,但可以改善 JVM 的整体性能表现。
【了解】在备用内存设备上进行堆分配
Java 10 支持将 JVM 堆分配到非易失性内存(NVM)或其他备用内存设备上:
# 使用备用内存设备
java -XX:AllocateHeapAt=/mnt/pmem MyApp这个特性主要用于:
利用大容量持久内存
减少应用重启时的数据重建时间
支持更大的堆内存配置
【了解】根证书
Java 10 在默认的 TrustStore 中包含了一组根证书颁发机构(CA)证书,解决了 OpenJDK 构建版本中缺少根证书的问题。
这意味着 OpenJDK 现在可以直接支持 TLS 连接,无需额外配置证书:
// 现在可以直接使用 HTTPS 连接
URL url = new URL("https://www.example.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// 无需额外的证书配置【了解】基于时间的版本发布
Java 10 确立了基于时间的发布模式:
每 6 个月发布一个新版本(3月和9月)
每 3 年发布一个 LTS 版本
版本号格式:年份.月份(如 18.3 表示 2018年3月)
这个改变让 Java 的发展更加可预测,新特性能更快地到达开发者手中。
API 改进
【了解】Optional 增强
Optional 类新增了 orElseThrow() 方法,作为 get() 的更好替代:
Optional<String> optional = Optional.of("Hello");
// Java 10 新增的方法
String value1 = optional.orElseThrow(); // 等同于 get(),但语义更清晰
// 相比传统的 get() 方法,orElseThrow() 语义更明确
String value2 = optional.get(); // 不推荐,语义不清【了解】Collection 增强
Collection 接口新增了 copyOf() 方法,可以创建不可变的副本:
List<String> original = new ArrayList<>();
original.add("A");
original.add("B");
// 创建不可变副本
List<String> copy = List.copyOf(original);
// copy.add("C"); // 会抛出 UnsupportedOperationException
Set<Integer> originalSet = new HashSet<>();
originalSet.add(1);
originalSet.add(2);
Set<Integer> copySet = Set.copyOf(originalSet);【了解】Collectors 增强
Collectors 类新增了 toUnmodifiableList()、toUnmodifiableSet() 和 toUnmodifiableMap() 方法:
List<String> names = List.of("张三", "李四", "王五");
// 收集到不可变列表
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toUnmodifiableList());
// 收集到不可变集合
Set<Integer> lengths = names.stream()
.map(String::length)
.collect(Collectors.toUnmodifiableSet());
// 收集到不可变映射
Map<String, Integer> nameLength = names.stream()
.collect(Collectors.toUnmodifiableMap(
name -> name,
String::length
));总结
Java 10 虽然特性不多,但 var 关键字的引入还是很有意义的,让 Java 代码可以更加简洁。应用程序类数据共享和 G1 的改进也为性能优化提供了新的选择。
最重要的是,Java 10 确立了新的发布节奏,为后续版本的快速迭代奠定了基础。虽然不是 LTS 版本,但它标志着 Java 进入了一个新的发展阶段。