Java 9 新特性
模块系统 JPMS、JShell、集合工厂方法与 Stream 增强。
模块系统(JPMS)
module-info.java declares the module name, its dependencies (requires) and the packages it exposes (exports). It fixes classpath clashes and encapsulation leaks — the headline Java 9 feature.
// 文件:module-info.java,放在源码根目录
module com.example.app {
requires java.sql;
requires java.logging;
exports com.example.api;
// 不 exports 的包,其他模块即使能 require 也访问不到
}module-info.java (they land in the unnamed module). You need it when publishing a library, enforcing API boundaries, or trimming the runtime with jlink.JShell
jshell is the official REPL: try statements without a class or main. It supports variables, method definitions, /vars to list them and /exit to leave.
$ jshell
| 欢迎使用 JShell -- 版本 21.0.2
jshell> 1 + 1
$1 ==> 2
jshell> "abc".toUpperCase()
$2 ==> "ABC"
jshell> /exit集合工厂方法
List.of, Set.of and Map.of build immutable collections in one line — safer than Arrays.asList, which is fixed-size but mutable. They reject null elements.
import java.util.List;
import java.util.Map;
import java.util.Set;
public class FactoryDemo {
public static void main(String[] args) {
List<String> list = List.of("a", "b");
Set<Integer> set = Set.of(1, 2);
Map<String, Integer> map = Map.of("a", 1, "b", 2);
System.out.println(list);
System.out.println(set.size());
System.out.println(map.get("a"));
try {
list.add("c");
} catch (UnsupportedOperationException e) {
System.out.println("immutable");
}
}
}[a, b]
2
1
immutableStream 增强
takeWhile takes from the head until the predicate first fails, dropWhile discards that prefix, and ofNullable tolerates null. All three make stream code fit real data better.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Stream9Demo {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 10, 1);
System.out.println(nums.stream().takeWhile(n -> n < 5).collect(Collectors.toList()));
System.out.println(nums.stream().dropWhile(n -> n < 5).collect(Collectors.toList()));
System.out.println(Stream.ofNullable(null).count());
System.out.println(Stream.ofNullable("x").count());
}
}[1, 2, 3]
[10, 1]
0
1模块系统(JPMS)
module-info.java 声明模块名、依赖(requires)和对外暴露的包(exports)。它解决了 classpath 上的类冲突和封装泄漏,是 Java 9 最大的变化。
// 文件:module-info.java,放在源码根目录
module com.example.app {
requires java.sql;
requires java.logging;
exports com.example.api;
// 不 exports 的包,其他模块即使能 require 也访问不到
}module-info.java 也能正常跑(自动进入「未命名模块」)。只有当你要发布库、控制 API 边界,或者用 jlink 裁剪运行时才需要。JShell
jshell 是官方 REPL,不用写类和 main 就能试语句,适合验证 API 行为。支持变量、方法定义、/vars 查看变量、/exit 退出。
$ jshell
| 欢迎使用 JShell -- 版本 21.0.2
jshell> 1 + 1
$1 ==> 2
jshell> "abc".toUpperCase()
$2 ==> "ABC"
jshell> /exit集合工厂方法
List.of、Set.of、Map.of 一行创建不可变集合,比 Arrays.asList 更安全(后者长度固定但元素可改)。注意它们不接受 null 元素。
import java.util.List;
import java.util.Map;
import java.util.Set;
public class FactoryDemo {
public static void main(String[] args) {
List<String> list = List.of("a", "b");
Set<Integer> set = Set.of(1, 2);
Map<String, Integer> map = Map.of("a", 1, "b", 2);
System.out.println(list);
System.out.println(set.size());
System.out.println(map.get("a"));
try {
list.add("c");
} catch (UnsupportedOperationException e) {
System.out.println("immutable");
}
}
}[a, b]
2
1
immutableStream 增强
takeWhile 从头取到条件第一次为假、dropWhile 丢掉开头满足条件的元素、ofNullable 容忍 null。三者都让流式代码更贴近真实需求。
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Stream9Demo {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 10, 1);
System.out.println(nums.stream().takeWhile(n -> n < 5).collect(Collectors.toList()));
System.out.println(nums.stream().dropWhile(n -> n < 5).collect(Collectors.toList()));
System.out.println(Stream.ofNullable(null).count());
System.out.println(Stream.ofNullable("x").count());
}
}[1, 2, 3]
[10, 1]
0
1