Skip to content

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 GCParallel GC Full GC 多线程化
根证书开源OpenJDK 能力对齐
G1 改进自适应调整更智能

虽然不如 JDK 8、9 那样有 Lambda、Stream、模块系统这样的重磅功能,但这些改进让 Java 越来越好用。

基于 VitePress 构建