知识模块
☕ Java 知识模块
六、Java 新特性
JDK9-11 新特性

JDK9-11 新特性

面试提问

"JDK9-11 有哪些重要新特性?"


JDK 9 新特性

1. 模块化系统(JPMS)

// module-info.java
module com.example.myapp {
    requires java.sql;           // 依赖模块
    requires transitive java.logging;  // 传递依赖
    exports com.example.api;    // 导出包
    opens com.example.internal to com.example.tests;  // 反射访问
    uses com.example.Service;   // 使用服务
    provides Service with ServiceImpl;  // 提供服务
}

优点

  • 更强的封装性
  • 更小的运行时(jlink 定制 JRE)
  • 更好的安全性

2. JShell(交互式编程)

jshell> int add(int a, int b) { return a + b; }
jshell> add(1, 2)
$2 ==> 3

3. 接口私有方法

public interface MyInterface {
    default void method1() {
        privateMethod();  // 调用私有方法
    }
    
    default void method2() {
        privateMethod();
    }
    
    // 私有方法(JDK 9+)
    private void privateMethod() {
        System.out.println("Common logic");
    }
}

4. try-with-resources 增强

// JDK 8:需要在 try 中声明
try (InputStream is = new FileInputStream("file.txt")) {
    // ...
}
 
// JDK 9:可使用已声明的变量
InputStream is = new FileInputStream("file.txt");
try (is) {  // 直接使用
    // ...
}

5. 不可变集合工厂方法

// JDK 8
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
List<String> unmodifiable = Collections.unmodifiableList(list);
 
// JDK 9+ 工厂方法
List<String> list = List.of("a", "b", "c");
Set<String> set = Set.of("a", "b", "c");
Map<String, Integer> map = Map.of("a", 1, "b", 2);
 
// 注意:不可变,以下操作抛异常
// list.add("d");  // UnsupportedOperationException

6. Stream API 增强

// takeWhile:取到第一个不满足条件的元素
Stream.of(1, 2, 3, 4, 5, 3, 2, 1)
    .takeWhile(n -> n < 4)
    .forEach(System.out::print);  // 1 2 3
 
// dropWhile:丢弃到第一个不满足条件的元素
Stream.of(1, 2, 3, 4, 5, 3, 2, 1)
    .dropWhile(n -> n < 4)
    .forEach(System.out::print);  // 4 5 3 2 1
 
// ofNullable:创建可能为空的 Stream
Stream<String> s = Stream.ofNullable(null);  // 空流
 
// iterate:带终止条件
Stream.iterate(1, n -> n < 10, n -> n + 1)
    .forEach(System.out::print);  // 1 2 3 4 5 6 7 8 9

7. Optional 增强

// ifPresentOrElse
Optional.of("value").ifPresentOrElse(
    v -> System.out.println("有值: " + v),
    () -> System.out.println("无值")
);
 
// or
Optional.empty().or(() -> Optional.of("默认值"));  // Optional[默认值]
 
// stream
Optional.of("value").stream();  // Stream["value"]

JDK 10 新特性

1. var 局部变量类型推断

// 编译器自动推断类型
var list = new ArrayList<String>();  // ArrayList<String>
var stream = list.stream();          // Stream<String>
var map = new HashMap<String, Integer>();  // HashMap<String, Integer>
 
// 注意事项
var a = 1;          // int
var b = 1.0;        // double
var c = "hello";    // String
var d = List.of(1, 2, 3);  // List<Integer>
 
// 不能使用 var 的场景
// var x;                    // 错误:必须初始化
// var x = null;             // 错误:无法推断类型
// var x = () -> {};         // 错误:Lambda 需要明确类型
// class Field { var x = 1; } // 错误:不能用于字段

2. 不可变集合增强

// copyOf:创建不可变副本
List<String> mutable = new ArrayList<>(List.of("a", "b"));
List<String> immutable = List.copyOf(mutable);
 
// 如果原集合已经是不可变的,直接返回
List<String> original = List.of("a", "b");
List<String> copy = List.copyOf(original);  // 返回同一个实例

3. Optional 增强

// orElseThrow():无参版本,默认抛 NoSuchElementException
Optional.empty().orElseThrow();  // 抛异常

JDK 11 新特性

1. 字符串方法增强

// isBlank:判断空白
"  ".isBlank();  // true
"".isBlank();    // true
"hello".isBlank();  // false
 
// lines:按行分割
"a\nb\nc".lines().forEach(System.out::println);
 
// strip:去除首尾空白(支持 Unicode)
"  hello  ".strip();   // "hello"
"  hello  ".trim();    // "hello"
"\u2000hello\u2000".strip();  // "hello"(Unicode 空白)
"\u2000hello\u2000".trim();   // 不去除 Unicode 空白
 
// stripLeading / stripTrailing
"  hello  ".stripLeading();   // "hello  "
"  hello  ".stripTrailing();  // "  hello"
 
// repeat:重复
"ab".repeat(3);  // "ababab"

2. 文件读写简化

// 读取文件为字符串
String content = Files.readString(Path.of("file.txt"));
 
// 写入字符串到文件
Files.writeString(Path.of("file.txt"), "Hello World");

3. 集合转数组

// JDK 8
List<String> list = List.of("a", "b", "c");
String[] arr = list.toArray(new String[0]);
 
// JDK 11
String[] arr = list.toArray(String[]::new);

4. Lambda 参数使用 var

// 可以使用 var 声明参数
list.stream()
    .map((var s) -> s.toUpperCase())
    .forEach(System.out::println);
 
// 可以添加注解
list.stream()
    .map((@NonNull var s) -> s.toUpperCase())
    .forEach(System.out::println);

5. HTTP Client(标准化)

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com"))
    .build();
 
// 同步请求
HttpResponse<String> response = client.send(
    request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
 
// 异步请求
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);

版本特性对比

特性JDK 9JDK 10JDK 11
模块化--
var 类型推断-
接口私有方法--
不可变集合工厂增强-
Stream 增强--
Optional 增强-
字符串增强--
HTTP Client孵化孵化✅ 正式
单文件执行--

单文件执行(JDK 11)

# 直接执行 Java 文件(无需先编译)
java HelloWorld.java
 
# 带参数
java HelloWorld.java arg1 arg2

面试要点总结

问题答案要点
JDK 9 模块化?module-info.java,更强封装
JDK 10 var?局部变量类型推断,必须初始化
JDK 11 字符串?isBlank、lines、strip、repeat
JDK 9 集合工厂?List.of()、Set.of()、Map.of()

参考资料