JDK 10 其他特性
JDK 10 没有像 JDK 8、9 那样的大改动,但它引入了一些实用的语言和 API 改进。
集合 copyOf
JDK 10 为 List、Set、Map 添加了 copyOf 方法,用于创建不可变副本:
java
import java.util.*;
public class CopyOfDemo {
public static void main(String[] args) {
// List.copyOf
List<String> original = new ArrayList<>();
original.add("a");
original.add("b");
List<String> immutable = List.copyOf(original);
System.out.println(immutable); // [a, b]
// 原列表修改不影响副本
original.add("c");
System.out.println(original); // [a, b, c]
System.out.println(immutable); // [a, b](不变)
// 试图修改副本会抛异常
// immutable.add("d"); // UnsupportedOperationException
// Set.copyOf
Set<Integer> set = new HashSet<>(Set.of(1, 2, 3));
Set<Integer> immutableSet = Set.copyOf(set);
System.out.println(immutableSet); // [1, 2, 3](顺序不确定)
// Map.copyOf
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
Map<String, Integer> immutableMap = Map.copyOf(map);
System.out.println(immutableMap); // {a=1, b=2}
// 使用场景:返回安全副本
List<String> getNames() {
List<String> internal = fetchFromDatabase();
return List.copyOf(internal); // 返回不可变副本
}
}
}与工厂方法的区别
java
// 工厂方法:直接创建不可变集合
List<String> list1 = List.of("a", "b", "c");
// copyOf:从已有集合创建不可变副本
List<String> list2 = List.copyOf(existingList);
// 两者结果类似,但:
// - List.of() 更简洁,适合字面量
// - List.copyOf() 适合从变量创建并行 Full GC
JDK 10 改进了 Parallel GC 的 Full GC,使其支持并行:
bash
# 启用并行 Full GC(JDK 10+ 默认开启)
java -XX:+UseParallelGC -jar app.jar
# JDK 9 之前:Full GC 是单线程的
# JDK 10+:Full GC 也会使用多线程(如果可用)这对于大堆应用(几十 GB)有明显改善。
线程局部变量控制台
JDK 10 允许在运行时检测和控制线程的 JVM TI 功能:
bash
# 启用线程局部握手
java -XX:+UseTLAB -XX:+UnlockCommercialFeatures \
-XX:+FlightRecorder ...
# 这为 JMC、async-profiler 等工具提供更好的线程控制能力Optional / Stream 增强
Optional.orElseThrow(JDK 10+)
java
import java.util.Optional;
public class OptionalOrElseThrow {
// JDK 10+:orElseThrow() 不需要参数
public String findName(Long id) {
return findById(id)
.orElseThrow(); // JDK 10+,直接抛 NoSuchElementException
}
// JDK 8:需要显式传异常工厂
public String findNameJDK8(Long id) {
return findById(id)
.orElseThrow(() -> new NoSuchElementException("User not found: " + id));
}
private Optional<String> findById(Long id) {
return id == 1 ? Optional.of("Alice") : Optional.empty();
}
}Stream.toList(JDK 16+)
java
import java.util.stream.*;
// JDK 16+:Stream.toList() 是 List 的快捷方式
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.toList(); // 等价于 .collect(Collectors.toList())
// JDK 8-15:只能用 .collect(Collectors.toList())根证书
JDK 10 把 Oracle JDK 的根证书开源了(Oracle 收购 Sun 之前是封闭的):
bash
# 查看可用证书
keytool -list -cacerts -storepass changeit | head -20
# 这让 OpenJDK 和 Oracle JDK 在 TLS/SSL 能力上更加一致基于 Java 的启动器
JDK 10 引入了用 Java 编写的实验性启动器:
bash
# java.lang.SourceVersion API 可以查询编译器版本信息
javac --version
javac -version这个改进为未来的 JIT/AOT 集成奠定了基础。
内存管理改进
G1 的并行 Full GC(JDK 10)
bash
# JDK 10 之前:Full GC 单线程
# JDK 10+:Full GC 多线程(在 G1 特定情况下)
java -XX:+UseG1GC -XX:+ParallelRefProcEnabled -jar app.jar堆内存自适应调整
bash
# JDK 10 改进了自适应调整策略
# 新参数 -XX:G1NewSizePercent 控制年轻代最小比例
# -XX:G1MaxNewSizePercent 控制年轻代最大比例
java -XX:G1NewSizePercent=20 \
-XX:G1MaxNewSizePercent=60 \
-XX:+UseG1GC \
-jar app.jar小结
JDK 10 是个小版本,但带来了一些有价值的改进:
| 改进 | 说明 |
|---|---|
List.copyOf() | 创建不可变副本 |
Optional.orElseThrow() | 无参版本 |
| 并行 Full GC | Parallel GC Full GC 多线程化 |
| 根证书开源 | OpenJDK 能力对齐 |
| G1 改进 | 自适应调整更智能 |
虽然不如 JDK 8、9 那样有 Lambda、Stream、模块系统这样的重磅功能,但这些改进让 Java 越来越好用。
