当前位置: 首页 > 教程 > Java9 >

Java9特性及示例

精华
小牛编辑
120浏览
2023-03-14

Java 9已经发布了有一段时间了,现在让我们来看看Java 9中的功能特性,看看它带给我们的哪些重大变化。

一些重要的Java 9特性是如下所示 -

  • Java 9 REPL(JShell)
  • 用于列表,集合,映射和Map.Entry的工厂方法
  • 接口的私有方法
  • Java 9模块系统
  • Process API改进
  • Try With Resources改进
  • CompletableFuture API改进
  • 反应流
  • 菱形运算符和匿名内部类
  • Optional类改进
  • 流API改进
  • 增强了@Deprecated注释
  • HTTP 2客户端
  • 多分辨率图像API
  • 其它杂项Java 9特性

Oracle公司将在2017年3月底前发布Java SE 9。在本文中,将通过一些示例简要讨论“Java 9功能”。

1. Java 9 REPL(JShell)

Oracle公司推出了一种名为“jshell”的新工具。 它代表Java Shell,也称为REPL(Read Evaluate Print Loop)。 它用于非常容易地执行和测试任何Java结构,如类,接口,枚举,对象,语句等。

运行效果如下所示 -

Oracle Corp引入了一些便利的工厂方法来创建Immutable ListSetMapMap.Entry对象。 这些实用程序方法用于创建空的或非空的集合对象。

2. 用于不可变列表,集合,映射和Map.Entry的工厂方法

在Java SE 8和更早的版本中,我们可以使用不可修改的Collections类实用程序方法来创建Immutable Collection对象。 例如,如果想创建一个不可变列表,那么可以使用Collections.unmodifiableList方法。

然而这些Collections.unmodifiableXXX方法是非常繁琐和冗长的方法。为了克服这些缺点,Oracle公司在List,Set和Map接口中增加了一些实用方法。

List和Set接口具有of()方法来创建一个空的或不空的不可变列表或Set对象,如下所示:

空列表示例

List immutableList = List.of();

非空列表示例

List immutableList = List.of("one","two","three");

Map有两套方法:分别创建Immutable Map对象和Immutable Map.Entry对象的of()方法和Entries()方法。

空Map示例

jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}

非空映射示例

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}

3. 接口的私有方法

在Java 8中,可以使用DefaultStatic方法在接口中提供方法实现。 但是不能在接口中创建私有方法。

为了避免冗余代码和更多的重用性,Oracle公司将在Java SE 9接口中引入私有方法。 从Java SE 9开始,我们可以使用'private'关键字在接口中编写私有和私有静态方法。

这些私有方法与其他类私有方法相似,它们之间没有区别。

public interface Card{

  private Long createCardID(){
    // Method implementation goes here.
  }

  private static void displayCardDetails(){
    // Method implementation goes here.
  }

}

4. Java 9模块系统

模块系统是Java 9特性之一。 Oracle公司将引入以下功能作为Jigsaw项目的一部分。

  • 模块化JDK
  • 模块化Java源代码
  • 模块化运行时图像
  • 封装Java内部API
  • Java平台模块系统

在Java SE 9版本之前,使用Monolithic Jars来开发基于Java的应用程序。 这种架构有很多限制和缺点。 为了避免所有这些缺陷,Java SE 9随模块系统一起提供。

JDK 9即将推出92个模块(可能会在最终版本中发生变化)。 我们可以使用JDK模块,也可以创建自己的模块,如下所示:

简单模块示例

module com.foo.bar { }

这里我们使用'module'关键字来创建一个简单的模块。 每个模块都有一个名称,相关的代码和其他资源。

5. Process API改进

Java SE 9即将在Process API中进行一些改进。他们增加了一些新的类和方法来简化操作系统进程的控制和管理。

Process API中有两个新的接口:

java.lang.ProcessHandle
java.lang.ProcessHandle.Info

Process API示例

ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("Current Process Id: = " + currentProcess.getPid());

6. Try-With-Resources改进

我们知道,Java SE 7引入了一个新的异常处理结构:Try-With-Resources来自动管理资源。 这个新声明的主要目标是“自动更好的资源管理”。

Java SE 9将对此语句进行一些改进,以避免更多冗长并提高某些可读性。

Java SE 7示例

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}

Java SE 9示例

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}

7. CompletableFuture API改进

在Java SE 9中,Oracle Corp将改进CompletableFuture API来解决Java SE 8中出现的一些问题。它们将增加支持一些延迟和超时,一些实用方法和更好的子分类。

Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);

这里delayedExecutor()是静态工具方法,用于返回一个新的Executor,它在给定的延迟后将任务提交给缺省执行程序。

8. 反应流

现在,反应式编程在开发应用程序以获得一些优点方面变得非常流行。 Scala,Play,Akka等。框架已经集成了Reactive Streams并获得许多好处。 Oracle Corps还在Java SE 9中引入了新的Reactive Streams API。

Java SE 9 Reactive Streams API是一个发布/订阅框架,可以使用Java语言轻松实现异步,可伸缩和并行应用程序。

Java SE 9引入了以下API来开发基于Java的应用程序中的Reactive Streams。

  • java.util.concurrent.Flow
  • java.util.concurrent.Flow.Publisher
  • java.util.concurrent.Flow.Subscriber
  • java.util.concurrent.Flow.Processor

9. 菱形运算符匿名内部类

我们知道,Java SE 7引入了一项新功能:菱形运算符,以避免冗余代码和冗长,以提高可读性。 但是,在Java SE 8中,Oracle Corp(Java Library Developer)发现在使用带有匿名内部类的菱形(Diamond)操作符方面存在一些限制。 他们已经修复了这些问题并将作为Java 9的一部分发布。

 public List getEmployee(String empid){
     // Code to get Employee details from Data Store
     return new List(emp){ };
  }

这里只使用List而不指定类型参数。

10 Optional类改进

在Java SE 9中,Oracle公司为java.util.Optional类添加了一些有用的新方法。 在这里将通过一些简单的例子来讨论其中的一种方法:流方法

如果给定Optional对象中存在一个值,则此stream()方法将返回具有该值的顺序Stream。 否则,它将返回一个空流。
已经添加了stream()方法来延迟处理Optional对象,如下所示:

Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)

这里使用Optional.stream()方法将Employee对象的一个可选的Stream转换为一个Employee流,以便可以在结果代码中懒处理这个结果。

11. Stream API改进

在Java SE 9中,Oracle Corp为java.util.Stream接口添加了四个有用的新方法。 由于Stream是一个接口,所有这些新实现的方法都是默认方法。 其中两个非常重要:dropWhiletakeWhile方法

如果您熟悉Scala语言或任何函数编程语言,您一定会了解这些方法。 在编写一些功能样式代码时,这些是非常有用的方法。 在这里我们讨论takeWhile实用方法。

这个takeWhile()将一个谓词作为参数,并返回给定Stream值的一个子集的Stream,直到Predicate返回false。 如果第一个值不满足该谓词,它只会返回一个空的流。

jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4

12. 增强了@Deprecated注释

在Java SE 8和更早版本中,@Deprecated注释只是一个没有任何方法的Marker接口。 它用于标记一个Java API,它是一个类,字段,方法,接口,构造函数,枚举等。

在Java SE 9中,Oracle Corp增强了@Deprecated注释以提供有关不推荐使用的API的更多信息,并提供了一个工具来分析应用程序对不推荐使用的API的静态使用情况。 他们添加了两个方法到这个Deprecated接口:forRemoval和自此来提供这些信息。

13. HTTP2客户端

在Java SE 9中,Oracle Corp将发布新的HTTP 2客户端API以支持HTTP/2协议和WebSocket功能。 由于现有的或传统的HTTP客户端API有许多问题(例如支持HTTP/1.1协议,不支持HTTP/2协议和WebSocket,只能在阻塞模式和大量性能问题下工作),他们用新的HTTP替换了这个HttpURLConnection API 客户。

他们将在java.net.http包下引入新的HTTP 2客户端API。 它支持HTTP/1.1HTTP/2协议。 它支持同步(阻塞模式)和异步模式。 它支持使用WebSocket API的异步模式。

HTTP2客户端示例

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("http://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> http://rams4java.blogspot.co.uk/2016/05/java-news.html

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))

14. 多分辨率图像API

在Java SE 9中,甲骨文公司将推出一种新的多分辨率图像API。 此API中的重要接口是MultiResolutionImage,它在java.awt.image包中可用。

MultiResolutionImage封装了一组具有不同高度和宽度(即不同分辨率)的图像,并允许我们按照自己的要求查询它们。