一分钟掌握java9新特性

ops/2024/9/25 10:39:27/

try-with-resources语句

/**  * 在处理必须关闭的资源时,使用try-with-resources语句替代try-finally语句。 生成的代码更简洁,更清晰,并且生成的异常更有用  * java9 之前写法  */  
public static String readFile1(String fileName){  try (Reader inputString = new StringReader(fileName);  BufferedReader br = new BufferedReader(inputString)) {  return br.readLine();  } catch (IOException e) {  throw new RuntimeException(e);  }  
}  /**  * 在处理必须关闭的资源时,使用try-with-resources语句替代try-finally语句。 生成的代码更简洁,更清晰,并且生成的异常更有用  * java9之后写法  */  
public static String readFile2(String fileName){  Reader inputString = new StringReader(fileName);  BufferedReader br = new BufferedReader(inputString);  try (br) {  return br.readLine();  } catch (IOException e) {  throw new RuntimeException(e);  }  
}

改进的集合工厂方法

Java 9 提供了一些新的静态工厂方法 List.of(), Set.of(), 和 Map.of() 来创建不可变集合。

示例代码

public static void main(String[] args) {  List<Integer> list = List.of(1, 2, 3);  Set<Integer> set = Set.of(1, 2, 3);  Map<String, Integer> map = Map.of("one", 1, "two", 2, "three", 3);  System.out.println(list);  System.out.println(set);  System.out.println(map);  
}

控制台输出

[1, 2, 3]
[1, 2, 3] 
{two=2, three=3, one=1}

增强流(Stream)API

takeWhile 方法

takeWhile 方法允许你在满足给定的谓词条件下获取流中的元素,直到第一个不满足条件的元素出现为止。

示例代码

public static void main(String[] args) {  List<Integer> numbers = List.of(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("Take while: " + takeWhileList);  
}

控制台输出

Take while: [1, 2, 3, 4]

dropWhile 方法

dropWhile 方法则相反,它会跳过流中的元素,直到找到第一个满足给定谓词的元素,然后返回剩余的所有元素。

示例代码:

public static void main(String[] args) {  List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  List<Integer> dropWhileList = numbers.stream()  .dropWhile(n -> n < 5)  .collect(Collectors.toList());  System.out.println("Drop while: " + dropWhileList);  
}

控制台输出

Drop while: [5, 6, 7, 8, 9, 10]

ofNullable 方法

ofNullable 方法允许你从一个可能为 null 的值创建一个 Stream,如果值不是 null,则创建一个单元素流;如果是 null,则创建一个空流。

示例代码:

public static void main(String[] args) {  Optional<String> optionalString = Optional.of("Hello World");  Stream<String> stream = Stream.ofNullable(optionalString.orElse(null));  stream.forEach(System.out::println);  
}

控制台输出

Hello World

iterate 方法

iterate 方法允许你基于一个初始值和一个迭代函数来创建无限流,Java 9 为 iterate 方法增加了一个重载版本,允许你指定一个终止条件。

示例代码

public static void main(String[] args) {  // 使用 iterate 创建一个无限流,直到达到 10  Stream<Long> infiniteStream = Stream.iterate(0L, n -> n + 1);  // 限制流的大小  Stream<Long> limitedStream = infiniteStream.limit(10);  limitedStream.forEach(System.out::println);  // 使用 iterate 的重载版本,直到终止条件为 true Stream<Long> untilStream = Stream.iterate(0L, n -> n < 10, n -> n + 1);  untilStream.forEach(System.out::println);  
}

控制台输出

限制流的大小: 0 1 2 3 4 5 6 7 8 9 
终止条件为 true0 1 2 3 4 5 6 7 8 9

Optional 类的新方法

Java 9 为 Optional 类添加了一些新方法,如 ifPresentOrElseor

ifPresentOrElse

ifPresentOrElse 方法的作用是:如果Optional 中有值,则执行指定的操作;
如果没有值,则执行另一个操作。这个方法可以让我们在处理可选值时,避免使用多个if 语句,从而使代码更加简洁。

源码

void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
  • action :如果 Optional 中有值,则执行的操作。
  • emptyAction :如果 Optional 中没有值,则执行的操作。

示例代码

import java.util.Optional;public class IfPresentOrElseExample {public static void main(String[] args) {// 有值的情况Optional<String> optionalValue = Optional.of("Hello, World!");optionalValue.ifPresentOrElse(value -> System.out.println("Value is present: " + value),() -> System.out.println("Value is absent"));// 没有值的情况Optional<String> emptyValue = Optional.empty();emptyValue.ifPresentOrElse(value -> System.out.println("Value is present: " + value),() -> System.out.println("Value is absent"));}
}

控制台

Value is present: Hello, World!
Value is absent

or

or 方法的作用是:如果 Optional 中有值,则返回该值;如果没有值,则返回另一个 Optional 。这个方法使得我们可以提供一个备用的值或 Optional ,从而避免 null 的情况。

源码

Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)
  • supplier :如果 Optional 为空,则提供一个新的 Optional

示例代码

import java.util.Optional;public class OrExample {public static void main(String[] args) {// 有值的情况Optional<String> optionalValue = Optional.of("Hello");String result1 = optionalValue.or(() -> Optional.of("Default Value")).get();System.out.println("Result 1: " + result1); // 输出: Hello// 没有值的情况Optional<String> emptyValue = Optional.empty();String result2 = emptyValue.or(() -> Optional.of("Default Value")).get();System.out.println("Result 2: " + result2); // 输出: Default Value}
}

控制台

Result 1: Hello
Result 2: Default Value

总结

  • ifPresentOrElse 方法允许我们在处理 Optional 时,优雅地处理有值和无值的情况。
  • or 方法则提供了一种方式来指定备用的 Optional 值,以便在原始 Optional 为空时使用。
    这两个方法的引入,使得 Optional 的使用更加灵活和方便,帮助开发者更好地处理可能缺失的值。

反应式流(Reactive Streams)

Java 9 引入了对反应式编程的支持,提供了 Flow 类,用于处理异步数据流。 Flow 类是 Java 反应式流(Reactive Streams)规范的一部分,允许开发者以非阻塞的方式处理数据流,并支持背压(backpressure)机制。

Flow 类的核心组件

  1. Publisher:发布数据流的对象。
  2. Subscriber:订阅数据流的对象,负责处理接收到的数据。
  3. Subscription:连接发布者和订阅者的桥梁,负责请求数据和控制数据流。
  4. Processor:既是发布者又是订阅者,负责在数据流中进行处理。

示例代码

import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;/**  * 展示了如何使用 Flow 类创建一个发布者和一个订阅者。  */
public class ReactiveStreamsExample {public static void main(String[] args) {// 创建一个 SubmissionPublisher,作为发布者SubmissionPublisher<String> publisher = new SubmissionPublisher<>();// 创建一个订阅者Flow.Subscriber<String> subscriber = new Flow.Subscriber<>() {private Flow.Subscription subscription;@Overridepublic void onSubscribe(Flow.Subscription subscription) {this.subscription = subscription;// 请求1个数据subscription.request(1);}@Overridepublic void onNext(String item) {System.out.println("Received: " + item);// 处理完一个数据后,再请求下一个数据subscription.request(1);}@Overridepublic void onError(Throwable throwable) {System.err.println("Error: " + throwable.getMessage());}@Overridepublic void onComplete() {System.out.println("Processing complete.");}};// 将订阅者注册到发布者publisher.subscribe(subscriber);// 发布一些数据System.out.println("Publishing items...");for (int i = 1; i <= 5; i++) {publisher.submit("Item " + i);}// 关闭发布者publisher.close();}
}

代码解释

  1. SubmissionPublisher:这是一个实现了 Publisher 接口的类,允许我们手动提交数据。
  2. Subscriber:我们实现了 Flow.Subscriber 接口,定义了如何处理接收到的数据。
    • onSubscribe :当订阅者与发布者连接时调用,负责请求数据。
    • onNext :当接收到数据时调用,处理数据并请求下一个数据。
    • onError :处理错误情况。
    • onComplete :处理完成时的逻辑。
  3. 数据发布:我们在一个循环中发布了5个数据项,并在发布后关闭了发布者。

使用场景

  1. 实时数据处理
    • 在金融服务中,实时处理股票价格、交易数据等信息,反应式流可以帮助系统快速响应市场变化。
  2. 微服务架构
    • 在微服务架构中,各个服务之间通过消息队列进行通信。使用反应式流可以有效地处理来自不同服务的异步消息,提高系统的响应能力和可扩展性。
  3. Web 应用程序
    • 在高并发的 Web 应用中,反应式流可以用来处理用户请求,特别是当请求涉及到数据库查询或外部 API 调用时,可以避免阻塞主线程,提高用户体验。
  4. 数据流处理
    • 在数据分析和 ETL(提取、转换、加载)过程中,反应式流可以用于处理大量数据的流式传输和实时分析。
  5. 物联网(IoT)应用
    • 在物联网应用中,设备会不断生成数据,反应式流可以帮助处理这些数据流,进行实时监控和分析。
  6. 其他:
    • 结合当前的特性再应用到合适的场景中

总结

Java 9 的 Flow 类为开发者提供了一种强大的工具来处理异步数据流,支持非阻塞操作和背压机制。这使得反应式编程在现代应用中变得越来越重要,特别是在需要高并发、高可用性和实时处理的场景中。

JShell(交互式命令行工具)

JShell 是一个新的命令行工具,可以用来快速测试 Java 代码片段,而无需创建完整的 Java 程序。

//第一步 输入 jshell 进入 
PS D:\project\hot-sauce-2> jshell 
| 欢迎使用 JShell -- 版本 17.0.7 
| 要大致了解该版本, 请键入: /help intro //第二步 编写代码 
jshell> int sum(int a, int b) {
...> return a + b; 
...> } 
| 已创建 方法 sum(int,int) // 第三部 运行第二步代码,得到结果 
jshell> sum(5, 10) 
$2 ==> 15

接口中的私有方法

Java 9 允许在接口中声明私有方法,这可以用来实现共享逻辑。

示例代码

/**  * 接口  */  
public interface MyInterface {  // 私有方法  private void printMessage() {  System.out.println("This is a private method in an interface.");  }  // 默认方法  default void display() {  printMessage();  }  
}/**  * 实现*/  
public class MyClass implements MyInterface {  public static void main(String[] args) {  new MyClass().display();  }  
}

增强@Deprecated注解

在 Java 9 中, @Deprecated 注解得到了增强,提供了更多的信息以帮助开发者理解被弃用的 API 的状态。这一增强主要体现在两个新的元素的引入上:

1. forRemoval

  • 类型boolean
  • 说明:该元素指示被弃用的元素是否计划在未来的版本中移除。如果设置为 true ,表示这个元素在未来的某个版本中会被移除。这个信息对于开发者来说非常重要,因为它可以帮助他们决定是否应该立即迁移到替代方案。

2. since

  • 类型String
  • 说明:该元素用于指定自哪个版本开始该元素被弃用。这可以让开发者快速了解该 API 的弃用历史,从而更好地管理代码的兼容性。

代码示例

public class Example {/*** @deprecated This method is deprecated because it is inefficient.* It is recommended to use {@link #newMethod()} instead.* * @since 9* @forRemoval true*/@Deprecated(since = "9", forRemoval = true)public void oldMethod() {// old implementation}public void newMethod() {// new implementation}
}

在上面的示例中:

  • oldMethod 被标记为弃用,注解中包含了 since = "9" ,表示这个方法从 Java 9 开始被弃用。
  • forRemoval = true 表示这个方法计划在未来的版本中被移除。
  • 方法的文档注释中也建议使用 newMethod() 作为替代方案。

总结

Java 9 中对 @Deprecated 注解的增强使得开发者在使用被弃用的 API 时能够获得更多的上下文信息。这种增强有助于提高代码的可维护性,减少未来版本中的兼容性问题,促使开发者更早地迁移到更好的替代方案。通过明确标记弃用的原因和计划移除的时间,Java 9 使得 API 的管理变得更加清晰和高效。

CompletableFuture API

在 Java 9 中, CompletableFuture API 进行了多项增强,使得异步编程更加灵活和强大

1. 新的工厂方法

Java 9 引入了几个新的静态工厂方法,增强了 CompletableFuture 的创建和组合能力:

  • CompletableFuture.allOf(CompletableFuture<?>... futures)
    • 这个方法接受多个 CompletableFuture 对象,并在所有给定的 CompletableFuture 完成时完成。适用于需要等待多个异步任务完成的场景。
  • CompletableFuture.anyOf(CompletableFuture<?>... futures)
    • 这个方法接受多个 CompletableFuture 对象,并在其中任意一个完成时完成。适合用于需要在多个任务中选择第一个完成的任务的场景。
      示例代码
import java.util.concurrent.CompletableFuture;public class CompletableFutureExample {public static void main(String[] args) {CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {// 模拟耗时操作sleep(1000);return "Result from Future 1";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {sleep(2000);return "Result from Future 2";});// 使用 allOf 等待所有任务完成CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2);allOf.join(); // 阻塞直到所有任务完成// 输出结果System.out.println(future1.join());System.out.println(future2.join());// 使用 anyOf 等待任意一个任务完成CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2);System.out.println("First completed: " + anyOf.join());}private static void sleep(int millis) {try {Thread.sleep(millis);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

2. 异常处理增强

Java 9 对异常处理的支持进行了增强,特别是与异常处理和组合相关的方法:

  • handle(BiFunction<? super T, Throwable, ? extends U> fn)
    • 这个方法允许你在计算完成时处理结果或异常。无论是正常完成还是异常完成,都会调用提供的函数。
  • exceptionally(Function<? super Throwable, ? extends T> fn)
    • 用于处理异常的函数,如果 CompletableFuture 在计算过程中发生异常,则会调用这个函数。
      示例代码
import java.util.concurrent.CompletableFuture;public class CompletableFutureErrorHandlingExample {public static void main(String[] args) {CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 模拟异常if (true) throw new RuntimeException("Something went wrong!");return "Result";});future.handle((result, ex) -> {if (ex != null) {System.out.println("发生错误: " + ex.getMessage());return "备用结果";}return result;}).thenAccept(System.out::println);}
}

3. delayedExecutor 方法

Java 9 引入了 delayedExecutor 方法,允许你创建一个带有延迟的执行器,用于在指定的延迟后执行任务。

  • delayedExecutor(long delay, TimeUnit unit)
    • 返回一个 ExecutorService ,可以用来在指定的延迟后执行任务。
      示例代码
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;public class DelayedExecutorExample {public static void main(String[] args) {// 创建一个带有延迟的执行器ExecutorService executor = CompletableFuture.delayedExecutor(2, TimeUnit.SECONDS);CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {System.out.println("任务在延迟后执行");}, executor);// 等待任务完成future.join();System.out.println("主线程结束");}
}

4. 超时处理增强

Java 9 还增加了对超时处理的支持:

  • orTimeout(long timeout, TimeUnit unit)
    • 允许设置超时,如果在指定的时间内未完成,则会自动取消 CompletableFuture
  • completeOnTimeout(T value, long timeout, TimeUnit unit)
    • 允许在指定的超时时间内完成 CompletableFuture ,如果在超时之前没有完成,则会使用给定的值完成。

总结

Java 9 对 CompletableFuture 的增强使得异步编程更加灵活和强大,提供了更好的异常处理机制、组合方式和超时处理能力。通过新增的工厂方法和增强的方法,开发者可以更方便地处理并发任务,提高程序的响应性和可维护性。这些特性使得 CompletableFuture 成为处理异步编程的重要工具。

ProcessHandle 类增强

在 Java 9 中, ProcessHandle 类得到了增强,提供了一些新的特性和方法,使得对操作系统进程的管理和监控变得更加方便和高效。以下是 Java 9 中 ProcessHandle 的主要新特性:

1. 新增的静态方法

Java 9 引入了一些新的静态方法,使得获取当前进程的信息变得更加简单:

  • ProcessHandle.current()
    • 该方法返回当前 Java 进程的 ProcessHandle 实例。通过这个实例,开发者可以获取当前进程的 ID、状态等信息。

2. 进程信息获取

通过 ProcessHandle ,可以获取关于进程的多种信息:

  • pid()
    • 返回进程的唯一标识符(PID)。
  • info()
    • 返回一个 ProcessHandle.Info 对象,提供关于进程的详细信息,包括命令行、启动时间、用户等。
  • children()
    • 返回当前进程的子进程的 ProcessHandle 流。可以用于遍历当前进程的所有子进程。
  • parent()
    • 返回当前进程的父进程的 ProcessHandle (如果存在)。

3. 进程状态监控

Java 9 中的 ProcessHandle 提供了对进程状态的监控功能:

  • isAlive()
    • 检查进程是否仍在运行。

4. 进程终止

可以通过 ProcessHandle 来终止进程:

  • destroy()
    • 终止与该 ProcessHandle 关联的进程。

示例代码

import java.util.Optional;public class ProcessHandleExample {public static void main(String[] args) {// 获取当前进程的 ProcessHandleProcessHandle currentProcess = ProcessHandle.current();// 打印当前进程的 PIDSystem.out.println("Current Process ID: " + currentProcess.pid());// 获取进程信息ProcessHandle.Info info = currentProcess.info();System.out.println("Command: " + info.command().orElse("N/A"));System.out.println("Arguments: " + info.arguments().map(argsArray -> String.join(", ", argsArray)).orElse("N/A"));System.out.println("User: " + info.user().orElse("N/A"));System.out.println("Start Time: " + info.startInstant().orElse(null));// 检查进程是否存活System.out.println("Is Alive: " + currentProcess.isAlive());// 获取子进程currentProcess.children().forEach(child -> {System.out.println("Child Process ID: " + child.pid());});// 获取父进程Optional<ProcessHandle> parentProcess = currentProcess.parent();parentProcess.ifPresent(parent -> {System.out.println("Parent Process ID: " + parent.pid());});}
}

总结

Java 9 中对 ProcessHandle 的增强使得开发者能够更加方便地管理和监控操作系统进程。通过新增的方法,开发者可以轻松获取进程的基本信息、监控进程状态、获取子进程和父进程的信息,以及终止进程。这些特性为 Java 应用程序提供了更强大的进程管理能力,特别是在需要与底层操作系统进行交互的场景中。

其他

多分辨率图像API、内部类操作符、改进了JavaDocs、多版本共存JAR 等想要了解的同学可以进一步研究,在实际项目中使用极少,这么就不展开说明了


http://www.ppmy.cn/ops/95894.html

相关文章

网络协议栈应用层的意义(内含思维导图和解析图通俗易懂超易理解)

绪论​&#xff1a; “节省时间的方法就是全力以赴的将所要做的事情完美快速的做完&#xff0c;不留返工重新学习的时间&#xff0c;才能省下时间给其他你认为重要的东西。” 本章主要讲到OSI网络协议栈中的应用层的作用和再次在应用层的角度理解协议的具体意义&#xff0c;以及…

[SWPUCTF 2021 新生赛]babyrce

我们传cookie admin1 访问http://node5.anna.nssctf.cn:29911/rasalghul.php 在PHP中&#xff0c;preg_match函数是一个用于进行正则表达式匹配的内置函数。它可以通过正则表达式对一个字符串进行匹配&#xff0c;判断该字符串是否满足正则表达式的规则。 发现过滤空格&#x…

SQLALchemy ORM 的关联关系之 ORM 中的多对多

SQLALchemy ORM 的关联关系之 ORM 中的多对多 场景示例实现多对多关系定义模型插入和查询数据总结在 SQLAlchemy ORM 中,多对多(Many-to-Many)关联关系是一种常见的关系类型,它表示两个表中的行可以相互关联,即一个表中的多行可以与另一个表中的多行相关联。为了实现这种关…

Jmeter+Influxdb+Grafana平台监控性能测试过程(三种方式)

一、Jmeter自带插件监控 下载地址&#xff1a;Install :: JMeter-Plugins.org 安装&#xff1a;下载后文件为jmeter-plugins-manager-1.3.jar&#xff0c;将其放入jmeter安装目录下的lib/ext目录&#xff0c;然后重启jmeter&#xff0c;即可。 启动Jmeter&#xff0c;测试计…

无限金币版《废土世界》安卓手机游戏下载,游戏分享

《废土世界》&#xff08;JunkWorld&#xff09;是由IRONHIDE游戏工作室开发的一款塔防游戏&#xff0c;它将玩家带入一个荒凉、贫瘠的后末日世界&#xff0c;玩家需要带领一队拾荒者穿越沙漠和放射性沼泽&#xff0c;进行生存战斗。游戏以其战略深度和丰富的塔防元素为特色&am…

【自用】Python爬虫学习(六):通过m3u8文件下载ts文件并合并为.mp4文件

Python爬虫学习&#xff08;六&#xff09; 下载视频&#xff08;简单版&#xff09;的步骤介绍第一步&#xff1a;在网页上找到.m3u8文件第二步&#xff1a;通过.m3u8文件下载对应的.ts视频文件第三步&#xff1a;依据.m3u8文件合并.ts文件为一个.mp4文件 下载视频&#xff08…

打造高可用集群的基石:深度解析Keepalived实践与优化

高可用集群 集群类型 集群类型主要分为负载均衡集群&#xff08;LB&#xff09;、高可用集群&#xff08;HA&#xff09;和高性能计算集群&#xff08;HPC&#xff09;三大类。每种集群类型都有其特定的应用场景和优势。 1. 负载均衡集群&#xff08;LB&#xff09; 负载均衡集…

【ARM 芯片 安全与攻击 5.1 -- 瞬态攻击(Transient Execution Attack)】

文章目录 瞬态攻击(Transient Execution Attack)推测执行攻击乱序执行攻击瞬态攻击在 ARM 中的应用Spectre 攻击在 ARM 中的应用示例防御瞬态攻击的措施硬件层面软件层面Summary瞬态攻击(Transient Execution Attack) 瞬态攻击(Transient Execution Attack)是一种利用现…