Java 11 新特性:从模块化到 HTTP/2
Java 11 新特性:从模块化到 HTTP/2 深度解析
Java 11 作为长期支持(LTS)版本,不仅在 Java 9 和 Java 10 的基础上进行了改进,还引入了诸多新特性,如增强的模块化支持、新的字符串方法、Lambda 语法改进,以及最受关注的 HTTP/2 API。本文将通过深入解析 Java 11 的关键新特性,并配以详细代码示例,帮助开发者更好地理解和应用 Java 11。
1. Java 模块化(Jigsaw 项目改进)
1.1 模块化简介
模块化是 Java 9 引入的重要特性,Java 11 进一步完善了 Jigsaw 项目,使得开发者可以更加灵活地管理模块依赖关系,提高项目的安全性和可维护性。
模块化的核心概念:
- module-info.java:定义模块的依赖和可访问的 API。
- requires 关键字:声明模块依赖关系。
- exports 关键字:指定哪些包对外可见。
1.2 模块化示例
创建一个 Java 模块 com.example.hello
,并在其中定义一个简单的类。
1.2.1 创建模块目录结构
hello-module/
├── src/
│ ├── com.example.hello/
│ │ ├── module-info.java
│ │ ├── HelloWorld.java
1.2.2 module-info.java
module com.example.hello {
exports com.example.hello;
}
1.2.3 HelloWorld.java
package com.example.hello;
public class HelloWorld {
public static void sayHello() {
System.out.println("Hello, Java 11 Modules!");
}
}
编译并运行模块化代码:
javac -d out --module-source-path src $(find src -name "*.java")
java --module-path out -m com.example.hello/com.example.hello.HelloWorld
2. String API 增强
Java 11 对 String
类新增了多个实用方法,极大提升了日常开发的便利性。
2.1 isBlank()
:判断字符串是否为空白
public class StringBlankExample {
public static void main(String[] args) {
String str1 = " ";
String str2 = "Java 11";
System.out.println(str1.isBlank()); // true
System.out.println(str2.isBlank()); // false
}
}
2.2 strip()
:去除前后空格(兼容 Unicode 空格)
public class StringStripExample {
public static void main(String[] args) {
String str = " Java 11 ";
System.out.println(str.strip()); // "Java 11"
System.out.println(str.stripLeading()); // "Java 11 "
System.out.println(str.stripTrailing()); // " Java 11"
}
}
2.3 lines()
:按行拆分字符串
public class StringLinesExample {
public static void main(String[] args) {
String text = "Hello\nJava 11\nNew Features";
text.lines().forEach(System.out::println);
}
}
3. Lambda 语法增强(局部变量 var
支持)
Java 11 允许在 Lambda 表达式的参数中使用 var
关键字,增强了代码的可读性和一致性。
import java.util.List;
public class LambdaVarExample {
public static void main(String[] args) {
List<String> list = List.of("Java", "Python", "C++");
list.forEach((var lang) -> System.out.println(lang));
}
}
4. Java 11 HTTP/2 客户端 API
Java 11 引入了官方 HTTP/2 客户端 API,替代 HttpURLConnection
,支持异步和同步请求,提高了 HTTP 交互性能。
4.1 发送 GET 请求
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Http2GetExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://jsonplaceholder.typicode.com/posts/1"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
}
}
4.2 发送 POST 请求
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;
public class Http2PostExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String json = "{ \"title\": \"Java 11\", \"body\": \"HTTP/2 API\", \"userId\": 1 }";
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://jsonplaceholder.typicode.com/posts"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
}
}
5. ZGC(低延迟垃圾回收器)
ZGC(Z Garbage Collector)是 Java 11 引入的一种低延迟垃圾回收器,旨在减少 GC 停顿时间,提升系统吞吐量。
5.1 启用 ZGC
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar myapp.jar
5.2 ZGC 特性
- 低停顿时间:GC 过程不会超过 10ms,适用于大内存应用。
- 动态调整:适用于高吞吐量和大规模系统。
- 支持 Linux/x64:目前仅支持 Linux 平台(Java 11 版本)。
6. Optional
API 增强
Optional
类在 Java 11 进行了增强,新增了几个便捷方法,如 isEmpty()
和 orElseThrow()
,简化了空值处理,提高了代码可读性。
6.1 isEmpty()
方法
在 Java 8 及以前,我们通常使用 isPresent()
方法检查 Optional
是否有值,而 Java 11 提供了 isEmpty()
,使得代码更简洁。
import java.util.Optional;
public class OptionalIsEmptyExample {
public static void main(String[] args) {
Optional<String> emptyOpt = Optional.empty();
Optional<String> nonEmptyOpt = Optional.of("Java 11");
System.out.println(emptyOpt.isEmpty()); // true
System.out.println(nonEmptyOpt.isEmpty()); // false
}
}
6.2 orElseThrow()
方法
在 Java 8 中,我们通常使用 orElseThrow(Supplier<? extends Throwable>)
进行异常处理,而 Java 11 提供了一个无参数版本的 orElseThrow()
,默认抛出 NoSuchElementException
。
import java.util.Optional;
public class OptionalOrElseThrowExample {
public static void main(String[] args) {
Optional<String> emptyOpt = Optional.empty();
// 直接抛出 NoSuchElementException
String value = emptyOpt.orElseThrow();
System.out.println(value);
}
}
7. Files
API 新增 readString()
和 writeString()
方法
Java 11 进一步优化了 java.nio.file.Files
,新增了 readString()
和 writeString()
,简化了文件读写操作。
7.1 readString(Path)
读取文件内容
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FilesReadStringExample {
public static void main(String[] args) throws Exception {
Path path = Paths.get("sample.txt");
String content = Files.readString(path);
System.out.println(content);
}
}
7.2 writeString(Path, CharSequence)
写入文件
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FilesWriteStringExample {
public static void main(String[] args) throws Exception {
Path path = Paths.get("sample.txt");
String content = "Hello, Java 11!";
Files.writeString(path, content);
System.out.println("File written successfully!");
}
}
相比 Java 8 及以前的 Files.readAllBytes()
或 Files.write()
,新方法更加简洁且易读。
8. Collectors.toUnmodifiableList()
/ Set()
/ Map()
Java 11 引入了不可变集合收集器,使用 Collectors.toUnmodifiableList()
、toUnmodifiableSet()
和 toUnmodifiableMap()
,可以直接创建不可变集合,避免手动包装 Collections.unmodifiableList()
。
8.1 toUnmodifiableList()
示例
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CollectorsToUnmodifiableExample {
public static void main(String[] args) {
List<String> list = Stream.of("Java", "Python", "C++")
.collect(Collectors.toUnmodifiableList());
System.out.println(list);
// list.add("Go"); // UnsupportedOperationException
}
}
8.2 toUnmodifiableMap()
示例
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CollectorsToUnmodifiableMapExample {
public static void main(String[] args) {
Map<Integer, String> map = Stream.of("Java", "Python", "C++")
.collect(Collectors.toUnmodifiableMap(String::length, str -> str));
System.out.println(map);
// map.put(5, "Go"); // UnsupportedOperationException
}
}
这些方法创建的集合是不可变的,尝试修改会抛出 UnsupportedOperationException
,提高了代码的安全性。
9. Predicate.not()
方法
Java 11 为 Predicate
提供了 not()
方法,简化了 negate()
的写法,使得 Stream
代码更加直观。
9.1 传统 negate()
方法
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class PredicateNegateExample {
public static void main(String[] args) {
List<String> list = List.of("Java", "", "Python", "C++", "");
List<String> filteredList = list.stream()
.filter(Predicate.not(String::isEmpty))
.collect(Collectors.toList());
System.out.println(filteredList); // [Java, Python, C++]
}
}
相比 filter(s -> !s.isEmpty())
,Predicate.not(String::isEmpty)
更加直观,增强了可读性。
10. InputStream.transferTo(OutputStream)
方法
Java 11 增强了 InputStream
,提供了 transferTo()
方法,直接将数据传输到 OutputStream
,简化流拷贝操作。
10.1 transferTo()
示例
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class InputStreamTransferToExample {
public static void main(String[] args) {
try (InputStream inputStream = new FileInputStream("source.txt");
OutputStream outputStream = new FileOutputStream("destination.txt")) {
inputStream.transferTo(outputStream);
System.out.println("File copied successfully!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
相比传统的 while
读取循环,transferTo()
使代码更加简洁和高效。
11. String
类的 repeat(int count)
方法
Java 11 允许使用 repeat()
方法轻松重复字符串,而无需手动 StringBuilder
拼接。
public class StringRepeatExample {
public static void main(String[] args) {
String str = "Java ";
System.out.println(str.repeat(3)); // Java Java Java
}
}
比 for
循环拼接字符串更高效,代码更简洁。
12. Socket
API 改进
Java 11 重新实现了 java.net.Socket
和 java.net.ServerSocket
,提供了更好的性能和可维护性。
12.1 创建 TCP 服务器
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleTCPServer {
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
System.out.println("Server is listening on port 8080...");
while (true) {
try (Socket socket = serverSocket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true)) {
String message = reader.readLine();
System.out.println("Received: " + message);
writer.println("Echo: " + message);
}
}
}
}
}
Java 11 对 Socket
的底层实现进行了优化,使其性能更高,支持更好的扩展性。
总结
Java 11 作为长期支持(LTS)版本,不仅巩固了 Java 9 和 Java 10 的改进,还带来了诸多增强特性,包括模块化优化、全新的 HTTP/2 客户端 API、String
和 Optional
的新方法、Lambda 语法的增强、Files
API 的便捷读写方法,以及更高效的垃圾回收器 ZGC。此外,Collectors.toUnmodifiableList()
、Predicate.not()
、InputStream.transferTo()
等 API 提高了开发效率,使代码更加简洁易读。
对于仍在使用 Java 8 的开发者,Java 11 提供了充足的理由进行升级。无论是现代化 API、增强的性能,还是更安全的模块化体系,Java 11 都是目前生产环境中最值得采用的版本之一。
如果你想进一步优化 Java 11 应用,还可以探索 GraalVM、JVM 性能调优、并发优化 等更深层次的主题。Java 11 只是一个起点,未来的 Java 版本将继续演进,为开发者提供更强大的工具和更高效的运行环境。
- 点赞
- 收藏
- 关注作者
评论(0)