1. 引言

Java SE 10 的官方实现 JDK 10 于 2018 年 3 月 20 日正式发布。这次更新虽然不像 Java 8 那样带来革命性变化,但依然引入了不少实用的新特性与底层优化,尤其在开发体验、容器支持和性能调优方面有明显提升。

本文将系统梳理 Java 10 中的关键更新,帮助你快速掌握核心变化,避免踩坑,也为后续升级提供参考。


2. 局部变量类型推断(var)

这是 Java 10 最受关注的新特性,允许使用 var 关键字声明局部变量,由编译器自动推断类型。

适用场景

  • 变量初始化时右侧已明确类型
  • 提升代码可读性(尤其在泛型复杂时)

不适用场景

  • 初始化值为 null
  • Lambda 表达式或方法引用(编译器无法推断)

示例代码

@Test
public void givenValidStatements_whenUsingVar_thenSuccess() {
    var name = "Java 10";             // 推断为 String
    var list = List.of(1, 2, 3);      // 推断为 List<Integer>
    var stream = list.stream()         // 推断为 Stream<Integer>
                     .filter(i -> i > 1);

    assertEquals("Java 10", name);
    assertTrue(stream.count() == 2);
}

⚠️ 注意:var 仅用于局部变量,不能用于字段、方法参数或返回类型。

更深入的用法和限制,建议查看专题文章:Java 10 局部变量类型推断


3. 不可变集合增强

Java 10 对不可变集合的支持更加友好,新增了两个便捷方法,避免手动包装或使用 Collections.unmodifiableXXX()

3.1 List.copyOf(), Set.copyOf(), Map.copyOf()

直接从已有集合创建不可变副本,简单粗暴。

@Test(expected = UnsupportedOperationException.class)
public void whenModifyCopyOfList_thenThrowsException() {
    List<Integer> original = Arrays.asList(1, 2, 3);
    List<Integer> copyList = List.copyOf(original);
    
    copyList.add(4); // ❌ 抛出 UnsupportedOperationException
}

✅ 特点:

  • 若原集合已是不可变的,copyOf() 可能直接返回原引用(性能优化)
  • 空集合传入会返回标准的不可变空集合

3.2 Collectors.toUnmodifiableList/Set/Map

在 Stream 流水线中直接收集为不可变集合,告别中间可变状态。

@Test(expected = UnsupportedOperationException.class)
public void whenModifyToUnmodifiableList_thenThrowsException() {
    List<Integer> evenList = someIntList.stream()
        .filter(i -> i % 2 == 0)
        .collect(Collectors.toUnmodifiableList());
    
    evenList.add(4); // ❌ 同样抛异常
}

✅ 建议:在构建配置、缓存数据等场景优先使用,防止意外修改。


4. Optional.orElseThrow()

Optional 家族新增无参 orElseThrow() 方法,语义更清晰,**推荐替代 get()**。

@Test
public void whenListContainsInteger_OrElseThrowReturnsInteger() {
    Integer firstEven = someIntList.stream()
        .filter(i -> i % 2 == 0)
        .findFirst()
        .orElseThrow(); // 没有值时自动抛出 NoSuchElementException
    
    assertEquals(Integer.valueOf(2), firstEven);
}

✅ 优势:

  • 相比 get()orElseThrow() 明确表达了“期望有值,否则失败”的意图
  • 异常类型固定为 NoSuchElementException,便于统一处理

虽然行为与 get() 一致,但从代码可读性和最佳实践角度,应优先使用 orElseThrow()


5. 性能改进

Java 10 在底层做了多项性能优化,包括:

  • G1 垃圾回收器并行 Full GC 支持
  • 减少 GC 暂停时间
  • 字符串压缩优化

这些改进对应用透明,无需代码改动即可受益。

深入细节可参考:Java 10 性能提升详解


6. 容器环境感知能力

重大改进:JVM 现在能识别运行在 Docker 容器中,并自动读取容器限制(如 CPU 数、内存),而非宿主机资源。

适用平台

  • 仅支持 Linux(因依赖 cgroups)

默认行为

  • ✅ 启用容器支持:-XX:+UseContainerSupport(默认开启)
  • ❌ 可手动关闭:-XX:-UseContainerSupport

新增关键参数

参数 说明
-XX:ActiveProcessorCount=count 指定 JVM 使用的 CPU 核心数
-XX:InitialRAMPercentage=xx 初始堆内存占容器总内存百分比(默认 1.56%)
-XX:MaxRAMPercentage=xx 最大堆内存占比(默认 25%)
-XX:MinRAMPercentage=xx 最小堆内存占比

📌 踩坑提醒
在 Kubernetes 或 Docker 中部署时,若未设置内存限制,JVM 可能误判可用内存,导致 OOM。建议始终通过 -XX:MaxRAMPercentage 显式控制堆大小。


7. 根证书支持(Root Certificates)

OpenJDK 长期以来因缺少默认信任的根证书,导致 HTTPS、TLS 等安全协议无法开箱即用。

Java 10 起,Oracle 将其 Java SE Root CA 计划中的根证书开源,集成进 OpenJDK 的 cacerts 密钥库。

✅ 影响:

  • OpenJDK 构建版本 now supports TLS out of the box
  • 缩小了 OpenJDK 与 Oracle JDK 的差距
  • 开发者不再需要手动导入根证书

8. 已废弃和移除的内容

8.1 命令行工具移除

以下工具已被移除,建议使用替代方案:

已移除工具 替代方案 说明
javah javac -h 生成 JNI 头文件
policytool 文本编辑器 管理 java.policy 文件
java -Xprof jmap, jstat, Async-Profiler 性能分析

8.2 API 标记为待移除

以下 API 已被标记 forRemoval = true,未来版本将删除:

  • java.security.acl 包 ❌(推荐使用 java.security.Policy
  • java.security.Certificate
  • java.security.Identity, IdentityScope, Signer

⚠️ 建议:新项目避免使用,老项目尽早迁移。


9. 基于时间的版本发布模型

从 Java 10 开始,Oracle 正式采用时间驱动发布模式,彻底改变 Java 的演进节奏。

核心规则

  1. 每六个月发布一个新版本

    • 例如:JDK 10(2018.03)、JDK 11(2018.09)
  2. 功能版本支持周期为六个月

    • 仅维护到下一个版本发布为止
  3. 长期支持版本(LTS)每三年发布一次,支持三年

    • JDK 11 是第一个 LTS 版本(后续为 JDK 17、JDK 21...)
  4. java -version 输出包含 GA 日期,便于判断版本新旧

$ java -version
openjdk version "10" 2018-03-20
OpenJDK Runtime Environment 18.3 (build 10+46)
OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)

📌 对开发者的启示

  • 普通功能版本适合尝鲜,生产环境应优先选择 LTS 版本
  • 升级周期变短,需建立持续跟进机制

10. 总结

Java 10 虽然是一个短期功能版本,但引入了多项影响深远的改进:

  • var 提升编码效率
  • 不可变集合 API 更加现代化
  • 容器支持补齐云原生短板
  • 发布模型转向敏捷迭代

尽管 JDK 11 才是首个 LTS 版本,但 Java 10 标志着 Java 进入高速迭代时代。建议开发者理解其变化,为后续升级做好准备。

所有示例代码已托管至 GitHub:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-10


原始标题:New Features in Java 10

« 上一篇: Java Weekly, 第230期
» 下一篇: Java main() 详解