一、Java 11

北京时间 2018年9 月 26 日,Oracle 官方宣布 Java 11 正式发布。 这是 Java 大版本周期变化后的第一个长期支持版本, 非常值得关注。
从官网即可下载,最新发布的 Java11 将带来 ZGC、Http Client 等重要特性, 一共包含 17 个 JEP(JDK Enhancement Proposals, JDK 增强提案) 。 其实, 总共更新不止17个, 只是我们更关注如下的17个JEP更新。
Java11新特性 - 图1
JDK 11 将是一个 企业不可忽视的版本。 从时间节点来看, JDK 11 的发布正好处在 JDK 8 免费更新到期的前夕, 同时 JDK 9、 10 也陆续成为“历史版本” , 下面是 Oracle JDK 支持路线图:
Java11新特性 - 图2
JDK 11 是一个长期支持版本(LTS, Long-Term-Support)
对于企业来说, 选择 11 将意味着长期的、 可靠的、 可预测的技术路线图。
其中免费的OpenJDK11 确定将得到 OpenJDK 社区的长期支持, LTS 版本将是可以放心选择的版本。
从 JVM GC 的角度, JDK11 引入了两种新的 GC, 其中包括也许是划时代意义的 ZGC, 虽然其目前还是实验特性, 但是从能力上来看, 这是 JDK 的一个巨大突破, 为特定生产环境的苛刻需求提供了一个可能的选择。 例如, 对部分企业核心存储等产品, 如果能够保证不超过 10ms 的 GC 暂停, 可靠性会上一个大的台阶, 这是过去我们进行 GC 调优几乎做不到的, 是能与不能的问题。
按照官方的说法,新的发布周期会严格遵循时间点,将于每年的3月份和9月份发布。所以 Java 11 的版本号是18.9(LTS)。
不过与 Java 9 和 Java 10 这两个被称为“功能性的版本”不同(两者均只提供半年的技术支持), Java 11 不仅提供了长期支持服务,还将作为
Java 平台的参考实现。Oracle 直到2023年9月都会为Java 11 提供技术支持,而补丁和安全警告等扩展支持将持续到2026年。
Java11新特性 - 图3
Java11新特性 - 图4
新的长期支持版本每三年发布一次,根据后续的发布计划,下一个长期支持版 Java 17 将于2021年发布。
官网公开的 17 个 JEP( JDK Enhancement Proposal 特性增强提议)
Java11新特性 - 图5
Java11新特性 - 图6

二、JDK11 新增特性

1.字符串处理方法

Java11新特性 - 图7

2.Optional 加强

Optional 也增加了几个非常酷的方法,现在可以很方便的将一个 Optional 转换成一个 Stream,或者当一个空 Optional 时给它一个替代的。
Java11新特性 - 图8

3.局部变量类型推断升级

在var上添加注解的语法格式,在jdk10中是不能实现的。在JDK11中加入了这样的语法。
Java11新特性 - 图9

4.全新的 HTTP 客户端 API

HTTP,用于传输网页的协议,早在1997年就被采用在目前的1.1版本中。直到2015年, HTTP2才成为标准。
Java11新特性 - 图10
HTTP/1.1和HTTP/2的主要区别是如何在客户端和服务器之间构建和传输数据。
HTTP/1.1依赖于请求/响应周期。 HTTP/2允许服务器“push”数据:它可以发送比客户端请求更多的数据。 这使得它可以优先处理并发送对于首先加载网页至关重要的数据。
这是 Java 9 开始引入的一个处理 HTTP 请求的的 HTTP Client API, 该API 支持同步和异步, 而在 Java 11 中已经为正式可用状态, 你可以在java.net 包中找到这个 API。
它 将 替 代 仅 适 用 于 blocking 模 式 的 HttpURLConnection( HttpURLConnection是在HTTP 1.0的时代创建的, 并使用了协议无关的方法) , 并提供对WebSocket 和 HTTP/2的支持。

  1. HttpClient client = HttpClient.newHttpClient();
  2. HttpRequest request =
  3. HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/test/")).build();
  4. BodyHandler<String> responseBodyHandler = BodyHandlers.ofString();
  5. HttpResponse<String> response = client.send(request, responseBodyHandler);
  6. String body = response.body();
  7. System.out.println(body);
  8. HttpClient client = HttpClient.newHttpClient();
  9. HttpRequest request =
  10. HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/test/")).build();
  11. BodyHandler<String> responseBodyHandler = BodyHandlers.ofString();
  12. CompletableFuture<HttpResponse<String>> sendAsync =
  13. client.sendAsync(request, responseBodyHandler);
  14. sendAsync.thenApply(t -> t.body()).thenAccept(System.out::println);
  15. //HttpResponse<String> response = sendAsync.get();
  16. //String body = response.body();
  17. //System.out.println(body);

5.更简化的编译运行程序

看下面的代码:

  1. // 编译
  2. javac Javastack.java
  3. // 运行
  4. java Javastack

在我们的认知里面, 要运行一个 Java 源代码必须先编译, 再运行, 两步执行动作。
而在未来的 Java 11 版本中, 通过一个 java 命令就直接搞定了, 如以下所示:

  1. javac Javastack.java

一个命令编译运行源代码的注意点:
执行源文件中的第一个类, 第一个类必须包含主方法。
并且不可以使用其它源文件中的自定义类, 本文件中的自定义类是可以使用的。

6.废弃 Nashorn 引擎

废除Nashorn javascript引擎, 在后续版本准备移除掉, 有需要的可以考虑使用GraalVM。

7.ZGC

GC是java主要优势之一。 然而, 当GC停顿太长, 就会开始影响应用的响应时间。 消除或者减少GC停顿时长, java将对更广泛的应用场景是一个更有吸引力的平台。 此外, 现代系统中可用内存不断增长,用户和程序员希望JVM能够以高效的方式充分利用这些内存, 并且无需长时间的GC暂停时间。
ZGC, A Scalable Low-Latency Garbage Collector(Experimental)ZGC, 这应该是JDK11最为瞩目的特性, 没有之一。 但是后面带了Experimental,说明这还不建议用到生产环境。
ZGC 是一个并发, 基于region, 压缩型的垃圾收集器, 只有root扫描阶段会STW(stop the world), 因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。
优势:

  • GC暂停时间不会超过10ms;
  • 既能处理几百兆的小堆, 也能处理几个T的大堆(OMG);
  • 和G1相比, 应用吞吐能力不会下降超过15%;
  • 为未来的GC功能和利用colord指针以及Load barriers优化奠定基础;
  • 初始只支持64位系统;

ZGC的设计目标是:支持TB级内存容量, 暂停时间低(<10ms) , 对整个程序吞吐量的影响小于15%。 将来还可以扩展实现机制, 以支持不少令人兴奋的功能, 例如多层堆(即热对象置于DRAM和冷对象置于NVMe闪存) ,或压缩堆。

8.其他新特性

① Unicode10
② Deprecate the Pack200 Tools and API
③ 新的 Epsilon 垃圾收集器
④ 完全支持 Linux容器(包括Docker)
⑤ 支持 G1 上的并行完全垃圾收集
⑥ 最新的 HTTPS 安全协议TLS1.3
⑦ Java Flight Recorder

三、在当前 JDK 中看不到什么?

1.一个标准化和轻量级的JSON API

一个标准化和轻量级的JSON API被许多Java开发人员所青睐。 但是由于资金问题无法在Java当前版本中见到, 但并不会削减掉。 Java平台首席架构师Mark Reinhold在JDK 9邮件列中说: “这个JEP将是平台上的一个有用的补充, 但是在计划中, 它并不像Oracle资助的其他功能那么重要, 可能会重新考虑JDK 10或更高版本中实现。 ”

2.新的货币 API

对许多应用而言货币价值都是一个关键的特性, 但JDK对此却几乎没有任何支持。严格来讲, 现有的java.util.Currency类只是代表了当前ISO 4217货币的一个数据结构,但并没有关联的值或者自定义货币。 JDK对货币的运算及转换也没有内建的支持,
更别说有一个能够代表货币值的标准类型了。
此前, Oracle 公布的JSR 354定义了一套新的Java货币API: JavaMoney, 计划会在Java9中正式引入。 但是目前没有出现在JDK 新特性 中。
不过,如果你用的是Maven的话,可以做如下的添加,即可使用相关的API处理货币:

  1. <dependency>
  2. <groupId>org.javamoney</groupId>
  3. <artifactId>moneta</artifactId>
  4. <version>0.9</version>
  5. </dependency>

四、展望

随着云计算和 AI 等技术浪潮, 当前的计算模式和场景正在发生翻天覆地的变化, 不仅对 Java 的发展速度提出了更高要求, 也深刻影响着 Java 技术的发展方向。 传统的大型企业或互联网应用, 正在被云端、 容器化应用、 模块化的微服务甚至是函数(FaaS, Function-as-a-Service)所替代。
Java虽然标榜面向对象编程,却毫不顾忌的加入面向接口编程思想,又扯出匿名对象之概念,每增加一个新的东西,对Java的根本所在的面向对象思想的一次冲击。反观Python,抓住面向对象的本质,又能在函数编程思想方面游刃有余。 Java对标C/C++,以抛掉内存管理为卖点,却又陷入了JVM优化的噩梦。选择比努力更重要,选择Java的人更需要对它有更清晰的认识。
Java 需要在新的计算场景下,改进开发效率。 这话说的有点笼统,我谈一些自己的体会, Java 代码虽然进行了一些类型推断等改进,更易用的集合 API 等,但仍然给开发者留下了过于刻板、形式主义的印象,这是一个长期的改进方向。