Java 9 新特性

Java 9(2017 年发布)最大的动作是引入模块化系统 JPMS,同时带来一批"小而美"的语法改进。本节挑选日常开发最常用的几项,老项目升级后可以立刻用上。

模块化 JPMS(一句话)

模块化把 JDK 与应用程序拆成一个个 module,每个模块用 module-info.java 声明依赖与对外暴露的包:

module com.example.app {
    requires java.sql;        // 需要 java.sql 模块
    exports com.example.api;  // 只对外暴露 api 包
}

好处是依赖关系清晰、运行时体积更小;代价是迁移成本高,目前更多用于 JDK 自身与大型框架。

接口私有方法

Java 8 的接口允许 default/static 方法,但它们无法共用私有工具代码;Java 9 起接口可以定义 private 方法

public interface Greet {
    default void hello() {
        log();                          // 调用接口私有方法
        System.out.println("hello");
    }
    default void bye() {
        log();
        System.out.println("bye");
    }
    private void log() {                // Java 9 新增:接口私有方法
        System.out.println("打日志");
    }
}

两个 default 方法复用同一段日志逻辑,私有方法对外不可见,只能被本接口的方法调用。

钻石运算符用于匿名类

Java 7 的菱形运算符 <> 可用在普通类上,Java 9 起也能用在匿名内部类中:

// 片段需放进 main 方法中运行
List<String> list = new ArrayList<>() {   // Java 8 及以前会报错,Java 9 起允许
    { add("a"); add("b"); }               // 初始化块给匿名子类装数据
};
System.out.println(list.size());   // 输出:2

集合工厂方法 of

创建不可变集合不必再写 Arrays.asList 或多行 put,一行 of 搞定:

// 片段需放进 main 方法中运行
List<String> list = List.of("a", "b", "c");        // 不可变 List
Set<Integer> set = Set.of(1, 2, 3);                // 不可变 Set
Map<String, Integer> map = Map.of("语文", 90, "数学", 95);  // 不可变 Map
System.out.println(list.size());      // 输出:3
System.out.println(map.get("语文"));  // 输出:90

注意:of 创建的集合不允许增删改,也不能含 null,否则抛 UnsupportedOperationException 或 NullPointerException。

try-with-resources 改进

Java 7 要求资源在 try 的括号内创建;Java 9 起,已在外部声明且不会被改动的资源变量可直接放进 try:

// 片段需放进 main 方法中运行
BufferedReader br = new BufferedReader(
        new FileReader("a.txt"));   // 在 try 外创建
try (br) {                          // Java 9:直接放入已声明的资源
    System.out.println(br.readLine());
}

资源仍会在结束时自动关闭;多个资源可写 try (br1; br2) { ... }

REPL:jshell

JDK 9 自带交互式解释器 jshell,无需写类与 main 即可试验代码:

jshell> int a = 1 + 2;
a ==> 3
jshell> System.out.println(a * 2);
6
jshell> /exit

适合快速验证语法与小算法,是学习与调试的利器。

小结:Java 9 的模块化影响整体架构,接口私有方法与匿名类菱形运算符让写法更顺手;日常最常用的是 List.of/Map.of 创建不可变集合、改进版 try-with-resources 与命令行 jshell。

笔记加载中…