Java 8-17核心特性全景解析之Java9、10

Java 9 核心特性解析

Java 9在2017年9月发布,带来了模块系统等重大变革,是Java平台现代化的重要一步。

模块系统 (Project Jigsaw)

特性概述

模块系统是Java 9最重要的特性,旨在解决Java平台和应用程序的可伸缩性问题,提供更好的封装性和依赖管理。

技术细节

模块是一个自描述的Java代码和数据的集合,通过module-info.java文件定义:

// module-info.java
module com.example.myapp {
    // 导出包,使其对其他模块可见
    exports com.example.myapp.api;
    
    // 声明对其他模块的依赖
    requires java.base;  // 隐式依赖,可省略
    requires java.sql;
    
    // 允许反射访问
    opens com.example.myapp.internal to com.example.framework;
    
    // 提供服务实现
    provides com.example.service.MyService with com.example.myapp.impl.MyServiceImpl;
    
    // 使用服务
    uses com.example.service.OtherService;
}

模块系统的主要概念:

  • 强封装:默认情况下,模块中的包对其他模块不可见
  • 显式依赖:模块必须声明其依赖关系
  • 可靠配置:编译时和运行时都会验证模块依赖
  • 模块化JDK:JDK本身被分解为约100个模块
应用场景
  1. 大型应用模块化
// 应用API模块
module app.api {
    exports com.app.api;
}

// 应用实现模块
module app.impl {
    requires app.api;
    requires database.api;
    
    provides com.app.api.UserService with com.app.impl.UserServiceImpl;
}

// 数据库API模块
module database.api {
    exports com.db.api;
}

// 数据库实现模块
module database.impl {
    requires database.api;
    
    provides com.db.api.Repository with com.db.impl.JdbcRepository;
}
  1. 创建自定义运行时镜像
# 使用jlink创建包含所需模块的自定义运行时
jlink --module-path $JAVA_HOME/jmods:mods --add-modules app.main --output appruntime
  1. 服务加载
// 使用ServiceLoader加载服务实现
ServiceLoader<MyService> services = ServiceLoader.load(MyService.class);
for (MyService service : services) {
    service.doSomething();
}

JShell - 交互式Java REPL

特性概述

JShell是Java 9引入的交互式编程环境,允许开发者快速测试Java代码片段,无需编写完整的类或方法。

技术细节

JShell支持以下功能:

  • 执行表达式、语句和声明
  • 自动导入常用包
  • 代码补全和语法高亮
  • 访问执行历史
  • 保存和加载会话
# 启动JShell
$ jshell

# 执行简单表达式
jshell> 2 + 2
$1 ==> 4

# 定义变量
jshell> String greeting = "Hello, World!"
greeting ==> "Hello, World!"

# 定义方法
jshell> int sum(int a, int b) { return a + b; }
|  已创建 方法 sum(int,int)

# 使用方法
jshell> sum(10, 20)
$4 ==> 30

# 查看已定义的变量和方法
jshell> /vars
|    String greeting = "Hello, World!"
|    int $4 = 30

jshell> /methods
|    int sum(int,int)
应用场景
  1. 快速原型开发
// 测试新API
jshell> import java.net.http.*
jshell> var client = HttpClient.newHttpClient()
jshell> var request = HttpRequest.newBuilder().uri(URI.create("https://example.com")).build()
jshell> var response = client.send(request, HttpResponse.BodyHandlers.ofString())
jshell> response.body()
  1. 教学和学习
// 演示语言特性
jshell> var list = List.of(1, 2, 3, 4, 5)
jshell> list.stream().filter(n -> n % 2 == 0).map(n -> n * n).toList()
$2 ==> [4, 16]
  1. API探索
// 探索类方法
jshell> /imports
|    import java.io.*
|    import java.math.*
|    import java.net.*
// ...

jshell> String.class.getMethods()
// 显示String类的所有方法

集合工厂方法

特性概述

Java 9引入了创建不可变集合的便捷工厂方法,使创建小型集合实例更加简洁。

技术细节

新增的工厂方法包括:

  • List.of()
  • Set.of()
  • Map.of()Map.ofEntries()
// 创建不可变List
List<String> list = List.of("Java", "Python", "JavaScript");

// 创建不可变Set
Set<Integer> set = Set.of(1, 2, 3, 4, 5);

// 创建不可变Map (最多10个键值对)
Map<String, Integer> map = Map.of(
    "Java", 1995,
    "Python", 1991,
    "JavaScript", 1995
);

// 创建不可变Map (超过10个键值对)
Map<String, Integer> largeMap = Map.ofEntries(
    Map.entry("Java", 1995),
    Map.entry("Python", 1991),
    Map.entry("JavaScript", 1995),
    // ...更多条目
);

这些集合有以下特点:

  • 不可变(不支持添加、删除或替换元素)
  • 不允许null元素
  • 结构紧凑,内存效率高
  • 对于Map.of(),最多支持10个键值对
应用场景
  1. 常量集合定义
// 定义常量列表
private static final List<String> SUPPORTED_LANGUAGES = 
    List.of("Java", "Kotlin", "Scala", "Groovy");
  1. 方法返回值
// 返回不可变集合
public List<User> getDefaultUsers() {
    return List.of(
        new User("admin", Role.ADMIN),
        new User("guest", Role.GUEST)
    );
}
  1. 参数传递
// 传递不可变集合作为参数
processItems(Set.of("item1", "item2", "item3"));

接口私有方法

特性概述

Java 9允许在接口中定义私有方法,进一步增强了接口的封装能力,使默认方法的代码复用更加便捷。

技术细节

接口可以定义两种私有方法:

  • 私有实例方法:供默认方法调用
  • 私有静态方法:供静态方法和默认方法调用
public interface Logger {
    // 公共抽象方法
    void log(String message);
    
    // 默认方法
    default void logInfo(String message) {
        log(addSeverity("INFO", message));
    }
    
    default void logWarning(String message) {
        log(addSeverity("WARNING", message));
    }
    
    default void logError(String message) {
        log(addSeverity("ERROR", message));
    }
    
    // 私有方法 - 供默认方法复用
    private String addSeverity(String severity, String message) {
        return "[" + severity + "] " + message;
    }
    
    // 私有静态方法
    private static String getCurrentTimestamp() {
        return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    }
}
应用场景
  1. 代码复用
public interface PaymentProcessor {
    void processPayment(Payment payment);
    
    default void processDebitPayment(DebitPayment payment) {
        validatePayment(payment);
        processPayment(payment);
    }
    
    default void processCreditPayment(CreditPayment payment) {
        validatePayment(payment);
        processPayment(payment);
    }
    
    // 私有辅助方法
    private void validatePayment(Payment payment) {
        if (payment.getAmount() <= 0) {
            throw new IllegalArgumentException("Payment amount must be positive");
        }
        // 其他验证逻辑
    }
}
  1. 接口实现辅助
public interface DataProcessor {
    void process(List<String> data);
    
    default void processFile(Path filePath) throws IOException {
        process(readLines(filePath));
    }
    
    // 私有辅助方法
    private List<String> readLines(Path filePath) throws IOException {
        return Files.readAllLines(filePath);
    }
}

改进的Stream API

特性概述

Java 9对Stream API进行了增强,添加了几个新的方法,使流处理更加灵活和强大。

技术细节

新增的Stream方法包括:

  • takeWhile(): 依次获取满足条件的元素,直到遇到第一个不满足条件的元素
  • dropWhile(): 依次丢弃满足条件的元素,直到遇到第一个不满足条件的元素
  • ofNullable(): 创建一个包含单个元素的流,如果元素为null则创建空流
  • iterate(): 增强版的迭代方法,支持终止条件
// takeWhile 示例
Stream.of(1, 2, 3, 4, 5, 1, 2)
      .takeWhile(n -> n < 4)  // 获取元素直到遇到 >= 4 的元素
      .forEach(System.out::println);  // 输出: 1, 2, 3

// dropWhile 示例
Stream.of(1, 2, 3, 4, 5, 1, 2)
      .dropWhile(n -> n < 4)  // 丢弃元素直到遇到 >= 4 的元素
      .forEach(System.out::println);  // 输出: 4, 5, 1, 2

// ofNullable 示例
Stream<String> stream = Stream.ofNullable(getNullableValue());
// 如果getNullableValue()返回null,则stream是空流

// 带终止条件的iterate
Stream.iterate(1, n -> n <= 100, n -> n * 2)  // 从1开始,每次乘2,直到超过100
      .forEach(System.out::println);  // 输出: 1, 2, 4, 8, 16, 32, 64
应用场景
  1. 处理有序数据
// 处理有序日志,直到遇到错误日志
logs.stream()
    .takeWhile(log -> log.getLevel() != LogLevel.ERROR)
    .forEach(System.out::println);
  1. 数据分段处理
// 跳过所有小于阈值的数据,处理其余数据
measurements.stream()
    .dropWhile(m -> m.getValue() < threshold)
    .forEach(processor::process);
  1. 可能为空的数据处理
// 处理可能为null的用户数据
Stream.ofNullable(getUserData())
      .flatMap(Collection::stream)
      .forEach(this::processUserData);

其他重要特性

HTTP/2客户端 (孵化)

Java 9引入了新的HTTP客户端API (incubator),支持HTTP/2和WebSocket:

// 创建HTTP客户端
HttpClient client = HttpClient.newHttpClient();

// 构建请求
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com"))
    .GET()
    .build();

// 发送同步请求
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("状态码: " + response.statusCode());
System.out.println("响应体: " + response.body());

// 发送异步请求
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
      .thenApply(HttpResponse::body)
      .thenAccept(System.out::println)
      .join(); // 等待完成

// POST请求示例
HttpRequest postRequest = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com/users"))
    .timeout(Duration.ofSeconds(30))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("{\"name\":\"张三\",\"age\":30}"))
    .build();
多版本JAR文件

Java 9支持创建包含针对不同Java版本的类文件的JAR包:

multi-release-jar/
├── META-INF/
│   └── versions/
│       ├── 9/
│       │   └── com/example/
│       │       └── MyClass.class  # Java 9特定实现
│       └── 10/
│           └── com/example/
│               └── MyClass.class  # Java 10特定实现
└── com/
    └── example/
        └── MyClass.class          # 基础实现
改进的Javadoc

Java 9的Javadoc支持HTML5和搜索功能,并添加了新的标签:

/**
 * 这是一个示例类
 * 
 * @apiNote 这个API的使用注意事项
 * @implSpec 实现规范说明
 * @implNote 实现细节说明
 */
public class Example {
    // ...
}

Java 10 核心特性解析

Java 10于2018年3月发布,是Java采用新的六个月发布周期后的第一个版本,虽然特性较少,但引入了一些实用的改进。

局部变量类型推断 (var)

特性概述

Java 10引入了局部变量类型推断,允许使用var关键字声明局部变量,编译器会根据变量的初始化表达式自动推断其类型。

技术细节

var关键字的使用有以下限制:

  • 只能用于局部变量声明,不能用于方法参数、字段、返回类型等
  • 声明时必须初始化变量
  • 不能将值设为null
  • 不能用于lambda表达式的参数
// 基本用法
var text = "Hello, World!";              // 推断为String
var numbers = List.of(1, 2, 3, 4, 5);    // 推断为List<Integer>
var map = new HashMap<String, Integer>(); // 推断为HashMap<String, Integer>

// 循环中使用
for (var i = 0; i < 10; i++) {
    System.out.println(i);
}

// 增强for循环
for (var item : collection) {
    System.out.println(item);
}

// try-with-resources
try (var reader = new BufferedReader(new FileReader("file.txt"))) {
    // 使用reader
}

这些集合有以下特点:

  • 不可变(不支持添加、删除或替换元素)
  • 不允许null元素
  • 结构紧凑,内存效率高
  • 对于Map.of(),最多支持10个键值对
应用场景
  1. 减少冗长的类型声明
// 传统方式
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

// 使用var
var reader = new BufferedReader(new InputStreamReader(System.in));
  1. 使用匿名类
// 传统方式
Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
};

// 使用var
var comparator = new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
};
  1. 复杂泛型类型
// 传统方式
Map<String, List<Map<Integer, String>>> complexMap = new HashMap<>();

// 使用var
var complexMap = new HashMap<String, List<Map<Integer, String>>>();

G1垃圾收集器的并行Full GC

特性概述

Java 10将G1垃圾收集器的Full GC实现改为并行,显著提高了G1收集器在最坏情况下的性能。

技术细节

G1垃圾收集器在Java 9成为默认垃圾收集器,但其Full GC过程仍然是单线程的,这在大型堆上可能导致长时间停顿。Java 10改进了这一点:

  • 使用多线程并行标记-清除-压缩算法
  • 与之前的单线程实现相比,大幅减少了Full GC的停顿时间
  • 通过-XX:ParallelGCThreads参数控制并行线程数
# 启用G1收集器(Java 9+默认启用)
java -XX:+UseG1GC -XX:ParallelGCThreads=4 MyApplication
应用场景
  1. 大内存服务器应用
# 为大型服务器应用配置G1
java -XX:+UseG1GC -Xms4g -Xmx4g -XX:ParallelGCThreads=8 -XX:ConcGCThreads=2 ServerApplication
  1. 低延迟要求的应用
# 优化低延迟应用的GC配置
java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=45 LowLatencyApp

应用类数据共享 (Application Class-Data Sharing)

特性概述

Java 10扩展了类数据共享(CDS)功能,允许将应用类放入共享存档中,减少启动时间和内存占用。

技术细节

应用类数据共享(AppCDS)的工作流程:

  1. 创建类列表
  2. 创建共享存档
  3. 使用共享存档启动应用
# 步骤1:生成类列表
java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=classes.lst -cp app.jar MyApp

# 步骤2:创建共享存档
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=classes.lst -XX:SharedArchiveFile=app.jsa -cp app.jar

# 步骤3:使用共享存档启动应用
java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=app.jsa -cp app.jar MyApp
应用场景
  1. 微服务和容器化应用
# 为Docker容器中的微服务创建共享存档
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=microservice.lst -XX:SharedArchiveFile=microservice.jsa -cp microservice.jar
  1. 频繁启动的应用
# 优化命令行工具的启动时间
java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=tool.jsa -cp tool.jar CommandLineTool

其他重要特性

基于时间的发布版本控制

Java 10开始采用基于时间的版本号格式:$FEATURE.$INTERIM.$UPDATE.$PATCH

  • FEATURE:每六个月发布一次的功能版本
  • INTERIM:中间版本(预留)
  • UPDATE:兼容性更新版本
  • PATCH:紧急修复版本

例如:Java 10.0.1表示第10个功能版本的第1个更新版本。

统一的垃圾收集器接口

Java 10引入了一个统一的垃圾收集器接口,使得实现新的垃圾收集器更加容易,并简化了现有收集器的代码。

线程局部握手

Java 10引入了线程局部握手机制,允许JVM在不停止全部线程的情况下,停止单个线程,提高了GC等操作的效率。

移除了JavaEE和CORBA模块

Java 10移除了Java EE和CORBA模块,这些模块在Java 9中已被标记为废弃:

  • javax.activation
  • javax.xml.bind
  • javax.xml.ws
  • javax.xml.ws.annotation
  • javax.jws
  • javax.jws.soap
  • javax.transaction
  • javax.xml.soap
  • org.omg.CORBA
  • 等等
额外的Unicode语言标签扩展

Java 10增强了java.util.Locale类和相关的API,支持更多的BCP 47语言标签。

根证书

Java 10在JDK中添加了一组默认的根证书,提高了开箱即用的安全性.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值