Appearance
JDK 9-11 特性详解
JDK 9、10和11是Java语言发展的重要版本,引入了许多新特性和改进。本文将详细介绍这些版本的主要特性,并通过示例代码来说明其用法。
JDK 9 特性
1. 模块系统 (Project Jigsaw)
模块系统是JDK 9最显著的特性,它允许将代码组织成模块,每个模块都有明确的依赖关系。
模块定义
模块通过module-info.java文件定义:
java
module com.example.mymodule {
requires java.base;
requires java.sql;
exports com.example.mymodule.api;
opens com.example.mymodule.impl to com.example.othermodule;
}示例
步骤1: 创建模块
创建目录结构:
mymodule/ ├── src/ │ └── com.example.mymodule/ │ ├── module-info.java │ └── com/ │ └── example/ │ └── mymodule/ │ ├── api/ │ │ └── GreetingService.java │ └── impl/ │ └── GreetingServiceImpl.java编写
module-info.java:javamodule com.example.mymodule { exports com.example.mymodule.api; }编写
GreetingService.java:javapackage com.example.mymodule.api; public interface GreetingService { String greet(String name); }编写
GreetingServiceImpl.java:javapackage com.example.mymodule.impl; import com.example.mymodule.api.GreetingService; public class GreetingServiceImpl implements GreetingService { @Override public String greet(String name) { return "Hello, " + name + "!"; } }
步骤2: 使用模块
创建另一个模块:
app/ ├── src/ │ └── com.example.app/ │ ├── module-info.java │ └── com/ │ └── example/ │ └── app/ │ └── Main.java编写
module-info.java:javamodule com.example.app { requires com.example.mymodule; }编写
Main.java:javapackage com.example.app; import com.example.mymodule.api.GreetingService; import com.example.mymodule.impl.GreetingServiceImpl; public class Main { public static void main(String[] args) { GreetingService service = new GreetingServiceImpl(); System.out.println(service.greet("World")); } }
2. 接口中的私有方法
JDK 9允许在接口中定义私有方法,用于接口内部的代码复用。
示例
java
interface MyInterface {
default void defaultMethod() {
privateMethod();
System.out.println("Default method");
}
private void privateMethod() {
System.out.println("Private method");
}
}
class MyClass implements MyInterface {
public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.defaultMethod();
}
}
// 输出:
// Private method
// Default method3. 改进的Stream API
JDK 9为Stream API添加了几个新方法:
takeWhile(Predicate): 从流的开始获取元素,直到满足条件dropWhile(Predicate): 从流的开始丢弃元素,直到满足条件ofNullable(T): 创建一个可能包含null的流iterate(T, Predicate, UnaryOperator): 创建一个有限的流
示例
java
// takeWhile
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> takeWhileList = numbers.stream()
.takeWhile(n -> n < 5)
.collect(Collectors.toList());
System.out.println(takeWhileList); // 输出: [1, 2, 3, 4]
// dropWhile
List<Integer> dropWhileList = numbers.stream()
.dropWhile(n -> n < 5)
.collect(Collectors.toList());
System.out.println(dropWhileList); // 输出: [5, 6, 7, 8, 9, 10]
// ofNullable
Stream<String> stream1 = Stream.ofNullable("Hello");
Stream<String> stream2 = Stream.ofNullable(null);
System.out.println(stream1.count()); // 输出: 1
System.out.println(stream2.count()); // 输出: 0
// iterate
Stream<Integer> limitedStream = Stream.iterate(1, n -> n <= 10, n -> n + 1);
limitedStream.forEach(System.out::print); // 输出: 123456789104. 不可变集合工厂方法
JDK 9为集合框架添加了工厂方法,用于创建不可变集合。
示例
java
// 创建不可变List
List<String> immutableList = List.of("a", "b", "c");
// 创建不可变Set
Set<String> immutableSet = Set.of("a", "b", "c");
// 创建不可变Map
Map<String, Integer> immutableMap = Map.of(
"a", 1,
"b", 2,
"c", 3
);
// 创建不可变Map(键值对超过10个)
Map<String, Integer> largeImmutableMap = Map.ofEntries(
Map.entry("a", 1),
Map.entry("b", 2),
Map.entry("c", 3),
// 可以添加更多键值对
Map.entry("z", 26)
);5. HTTP/2 客户端
JDK 9引入了新的HTTP客户端API,支持HTTP/2和WebSocket。
示例
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
// 创建HTTP客户端
HttpClient client = HttpClient.newHttpClient();
// 创建请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/users/octocat"))
.build();
// 发送同步请求
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status code: " + response.statusCode());
System.out.println("Body: " + response.body());
// 发送异步请求
CompletableFuture<HttpResponse<String>> future = client.sendAsync(
request, HttpResponse.BodyHandlers.ofString()
);
future.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
}
}JDK 10 特性
1. 局部变量类型推断 (var关键字)
JDK 10引入了var关键字,允许编译器推断局部变量的类型。
示例
java
// 传统方式
String message = "Hello";
List<String> names = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
// 使用var
var messageVar = "Hello";
var namesVar = new ArrayList<String>();
var mapVar = new HashMap<String, Integer>();
// 与lambda表达式结合
var supplier = (Supplier<String>) () -> "Hello";
var function = (Function<Integer, String>) n -> "Number: " + n;
// 与流结合
var stream = List.of(1, 2, 3).stream();
var result = stream.filter(n -> n > 1)
.map(n -> n * 2)
.collect(Collectors.toList());2. 并行全垃圾收集器 (G1)
JDK 10使G1成为默认的垃圾收集器,替代了之前的Parallel GC。
3. 其他改进
- Application Class-Data Sharing: 允许在多个JVM之间共享类数据,减少启动时间和内存占用
- Thread-Local Handshakes: 允许在不停止整个线程的情况下执行线程回调
- Time-Based Release Versioning: 引入新的版本号方案,格式为
$FEATURE.$INTERIM.$UPDATE.$PATCH
JDK 11 特性
1. 标准HTTP客户端成为标准API
JDK 11将JDK 9中引入的HTTP客户端从孵化状态提升为标准API。
示例
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class StandardHttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}2. 字符串API增强
JDK 11为String类添加了几个新方法:
isBlank(): 检查字符串是否为空或只包含空白字符lines(): 将字符串按行分割成流strip(): 去除字符串首尾的空白字符(包括Unicode空白字符)stripLeading(): 去除字符串开头的空白字符stripTrailing(): 去除字符串结尾的空白字符repeat(int): 将字符串重复指定次数
示例
java
// isBlank
System.out.println(" ".isBlank()); // 输出: true
System.out.println("Hello".isBlank()); // 输出: false
// lines
String text = "Line 1\nLine 2\nLine 3";
text.lines().forEach(System.out::println);
// 输出:
// Line 1
// Line 2
// Line 3
// strip
String str = " Hello ";
System.out.println("strip(): '" + str.strip() + "'"); // 输出: 'Hello'
System.out.println("stripLeading(): '" + str.stripLeading() + "'"); // 输出: 'Hello '
System.out.println("stripTrailing(): '" + str.stripTrailing() + "'"); // 输出: ' Hello'
// repeat
String repeated = "Hello".repeat(3);
System.out.println(repeated); // 输出: HelloHelloHello3. 变量类型推断增强
JDK 11允许在lambda表达式中使用var关键字。
示例
java
// 传统lambda表达式
Function<Integer, String> func1 = (Integer n) -> "Number: " + n;
// JDK 11: 使用var
Function<Integer, String> func2 = (var n) -> "Number: " + n;
// 与泛型结合
BiFunction<T, U, R> biFunc = (var t, var u) -> { /* 实现 */ };4. 移除和废弃的特性
- 移除:com.sun.awt.AWTUtilities、sun.misc.Unsafe.defineClass、Thread.destroy()和Thread.stop(Throwable)方法
- 废弃:Nashorn JavaScript引擎、Pack200工具和API
5. ZGC垃圾收集器
JDK 11引入了实验性的ZGC垃圾收集器,它的特点是:
- 低延迟(暂停时间不超过10ms)
- 支持大堆(可达数TB)
- 对应用吞吐量的影响小
启用ZGC
bash
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xmx16g MyApp总结
JDK 9-11引入了许多重要的特性和改进,包括:
- JDK 9:模块系统、接口私有方法、改进的Stream API、不可变集合工厂方法、HTTP/2客户端
- JDK 10:局部变量类型推断、并行全垃圾收集器(G1)作为默认GC
- JDK 11:标准HTTP客户端、字符串API增强、lambda表达式中的var、ZGC垃圾收集器
这些特性使得Java语言更加现代化、高效和易用,为开发者提供了更多的工具和选择。