Java 9 新特性(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言

Java 9 是 Java 生态系统的一次重要升级,它不仅引入了模块化系统这一革命性功能,还通过一系列语法优化和 API 增强,让开发者能够更高效地构建和维护复杂项目。对于编程初学者而言,这些新特性降低了学习曲线;对于中级开发者,它们则提供了提升代码质量和可维护性的新工具。本文将逐一解析 Java 9 的核心新特性,并通过具体案例帮助读者理解其应用场景。


模块化系统(JPMS):Java 的“城市规划师”

Java 9 最引人注目的新特性是 Java Platform Module System (JPMS),它首次将模块化引入 Java 核心。模块化可以类比为“城市规划”:通过将代码划分为独立的模块(Module),开发者能明确依赖关系,避免“依赖地狱”问题。

模块化的核心概念

  • 模块声明(Module Declaration):每个模块通过 module-info.java 文件定义,声明导出的包和依赖的其他模块。
  • 包访问控制:默认情况下,包仅对模块内部可见,需显式导出(exports)才能被其他模块使用。
  • 服务提供者机制:通过 usesprovides 关键字,模块可以声明对服务接口的支持。

示例代码:定义一个简单模块

// module-info.java  
module my.module {  
    requires java.base; // 引用基础模块  
    exports my.module.utils; // 导出 utils 包  
    uses com.example.ServiceInterface; // 声明使用某个服务接口  
}

模块化的优势

  • 减少启动时间:通过类路径隔离,JVM 可以仅加载必要模块。
  • 提高安全性:限制包的可见性,减少未授权访问风险。
  • 清晰的依赖管理:模块间的依赖关系显式声明,避免隐式依赖。

新的集合工厂方法:让代码更简洁

Java 9 为 ListSetMap 接口引入了 静态工厂方法,简化了集合的创建和初始化。这些方法类似于 Arrays.asList(),但更灵活且返回不可变集合。

示例:创建不可变列表

List<String> fruits = List.of("Apple", "Banana", "Orange");  
// fruits.add("Grape"); // 抛出 UnsupportedOperationException  

集合工厂方法的特点

  • 类型推断:编译器自动推断元素类型,无需显式声明泛型。
  • 不可变性:返回的集合是只读的,避免意外修改。
  • 空安全:若传入 null 元素,会抛出 NullPointerException

对比:Java 8 与 Java 9 的代码差异

// Java 8  
List<String> oldList = new ArrayList<>();  
oldList.add("Java");  
oldList.add("Python");  

// Java 9  
List<String> newList = List.of("Java", "Python");  

私有接口方法:接口中的“共享工具箱”

在 Java 9 之前,接口只能定义默认方法和静态方法。Java 9 引入了 私有接口方法,允许在接口中定义私有辅助方法,供默认方法或静态方法调用。

为什么需要私有接口方法?

  • 代码复用:将重复逻辑封装在私有方法中,避免多个默认方法的冗余代码。
  • 封装性:私有方法对外不可见,确保接口的简洁性。

示例:计算器接口的私有方法

interface Calculator {  
    // 默认方法  
    default int add(int a, int b) {  
        return calculate(a, b, (x, y) -> x + y);  
    }  

    // 私有接口方法  
    private int calculate(int a, int b, BiFunction<Integer, Integer, Integer> op) {  
        return op.apply(a, b);  
    }  
}  

私有方法的限制

  • 只能在接口内部调用,无法被实现类或外部访问。
  • 不能声明为 staticpublic

var 关键字:局部变量的“类型推断”

Java 9 引入了 var 关键字,允许开发者在局部变量声明时省略显式类型,由编译器根据赋值表达式推断类型。这提升了代码的简洁性,但需谨慎使用以避免可读性下降。

使用场景与注意事项

  • 适用场景:变量初始化时类型明显,如循环变量、简单赋值。
  • 避免场景:复杂表达式或可能变更类型的变量。

示例:var 的典型用法

var numbers = List.of(1, 2, 3); // 推断为 List<Integer>  
var scanner = new Scanner(System.in); // 推断为 Scanner  

与 C# var 的对比

Java 的 var 仅限局部变量,且要求初始化时有明确的赋值表达式,而 C# 的 var 可用于字段和更复杂的上下文。


Stream API 的增强:更精准的数据处理

Java 9 扩展了 Stream 接口的功能,新增了 dropWhiletakeWhileofNullable 等方法,进一步简化流式数据处理。

新增方法详解

方法功能描述
takeWhile(Predicate)当条件满足时持续收集元素,条件不满足时终止。
dropWhile(Predicate)跳过满足条件的元素,直到条件不满足后收集剩余元素。
ofNullable(T)将可能为 null 的单个元素安全转换为 Stream。

示例:takeWhile 的实际应用

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);  
numbers.stream()  
    .takeWhile(n -> n < 4)  
    .forEach(System.out::print); // 输出 123  

JShell:Java 的“即时编程环境”

Java 9 内置了 JShell,这是一个交互式 Java REPL(Read-Eval-Print Loop),允许开发者直接执行代码片段并查看结果,极大提升了学习和调试效率。

JShell 的核心功能

  • 快速测试代码:无需编写完整类和方法,直接输入表达式即可。
  • 自动补全和错误提示:提供实时语法检查和上下文建议。
  • 会话管理:支持保存和恢复交互记录。

示例:在 JShell 中运行代码

jshell> int a = 10  
a ==> 10  

jshell> System.out.println("Hello, JShell!")  
Hello, JShell!  

新的 HTTP Client API:现代化的网络请求

Java 9 引入了 标准的 HTTP Client APIjava.net.http 包),替代了旧版的 HttpURLConnection,支持异步请求、WebSocket 和 HTTP/2 协议。

API 核心类

  • HttpClient:发送请求的客户端。
  • HttpRequest:构建 HTTP 请求对象。
  • HttpResponse:接收响应结果。

示例:发送 GET 请求

HttpClient client = HttpClient.newHttpClient();  
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.example.com/data"))  
    .GET()  
    .build();  

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());  
System.out.println(response.body());  

其他改进:细节优化与性能提升

1. Process API 的增强

新增了 ProcessHandle 类,支持监控和管理操作系统进程,例如:

Process process = Runtime.getRuntime().exec("ping localhost");  
ProcessHandle handle = ProcessHandle.of(process.pid());  
handle.info().command().ifPresent(System.out::println);  

2. 集合类的增强

  • Map.getOrDefault 方法简化了键不存在时的默认值获取。
  • Collection.removeIf 支持通过 Predicate 条件批量删除元素。

3. Optional 的新方法

Stream 可以直接从 Optional 生成:

Optional<String> maybeValue = Optional.of("Hello");  
maybeValue.stream().forEach(System.out::print); // 输出 Hello  

结论

Java 9 的新特性从模块化、语法糖到 API 增强,全面提升了 Java 的开发体验和工程实践。对于初学者,模块化和 var 等特性降低了代码复杂度;对于中级开发者,JShell 和 HTTP Client 则提供了更高效的工具链。掌握这些新特性,不仅能提高编码效率,还能为后续 Java 版本的升级打下坚实基础。

在实践中,建议读者通过实际项目逐步应用这些特性,并关注 Oracle 官方文档和社区讨论,以持续优化开发流程。Java 9 的诞生,标志着 Java 正朝着更模块化、更现代化的方向稳步前进。

最新发布