Java 11 新特性:从模块化到 HTTP/2

举报
江南清风起 发表于 2025/03/09 22:04:23 2025/03/09
【摘要】 Java 11 新特性:从模块化到 HTTP/2 深度解析Java 11 作为长期支持(LTS)版本,不仅在 Java 9 和 Java 10 的基础上进行了改进,还引入了诸多新特性,如增强的模块化支持、新的字符串方法、Lambda 语法改进,以及最受关注的 HTTP/2 API。本文将通过深入解析 Java 11 的关键新特性,并配以详细代码示例,帮助开发者更好地理解和应用 Java 1...

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.Socketjava.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、StringOptional 的新方法、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 版本将继续演进,为开发者提供更强大的工具和更高效的运行环境。

image.png

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。