前言
Java 11 已于 2018 年 9 月 25 日正式发布,为了加快的版本迭代、跟进社区反馈,Java 的版本发布周期调整为每六个月一次——即每半年发布一个大版本,每个季度发布一个中间特性版本,并且做出不会跳票的承诺。通过这样的方式,Java 开发团队能够将一些重要特性尽早的合并到 Java Release 版本中,以便快速得到开发者的反馈,避免出现类似 Java 9 发布时的两次延期的情况。
按照官方介绍,新的版本发布周期将会严格按照时间节点,于每年的 3 月和 9 月发布,Java 11 发布的时间节点也正好处于 Java 8 免费更新到期的前夕。与 Java 9 和 Java 10 这两个被称为"功能性的版本"不同,Java 11 仅将提供长期支持服务(LTS, Long-Term-Support),还将作为 Java 平台的默认支持版本,并且会提供技术支持直至 2023 年 9 月,对应的补丁和安全警告等支持将持续至 2026 年。
本文主要针对 Java 11 中的新特性展开介绍,快速了解 Java 11 带来的变化。
基于嵌套的访问控制
嵌套访问控制是一种控制上下文访问的策略,允许逻辑上属于同一代码实体,但被编译之后分为多个分散的 class 文件的类,无需编译器额外的创建可扩展的桥接访问方法,即可访问彼此的私有成员,并且这种改进是在 Java 字节码级别的。
在 Java 11 之前的版本中,编译之后的 class 文件中通过 InnerClasses 和 Enclosing Method 两种属性来帮助编译器确认源码的嵌套关系,每一个嵌套的类会编译到自己所在的 class 文件中,不同类的文件通过上面介绍的两种属性的来相互连接。这两种属性对于编译器确定相互之间的嵌套关系已经足够了,但是并不适用于访问控制。
Java 11 中引入了两个新的属性:一个叫做 NestMembers 的属性,用于标识其它已知的静态 nest 成员;另外一个是每个 nest 成员都包含的 NestHost 属性,用于标识出它的 nest 宿主类。
标准 HTTP Client 升级
在Java 9 中开始引入了一个用于处理HTTP请求的HTTP Client API, 该 API 支持同步和异步,而在 Java 11 中已经为正式可用状态,可以在 java.net 包中找到这个 API,看一下这个API的用法:
1 | String uri = "http://www.oracle.com/"; |
Http请求的默认方式为GET。我们终于可以摆脱老旧的HttpURLConnection了😄,但是是否可以真正地取代Apache的HttpClient工具包还待进一步验证。
字符串API加强
Java 11 对原来的字符串API进行了增强,下面的代码演示了其中部分增强的API用法:
1 | String s = "Javastack "; |
Java 启动器增强
在之前的版本,我们运行一个Java主类需要两步,即先编译然后再执行。而在Java 11 中,通过一个Java命令就可以搞定了:
1 | $ java Main.java |
用于 Lambda 参数的局部变量语法
本地变量类型var是java 10提出的新概念,它可以从上下文中推断出本地变量的类型,从而提高代码可读性。
1 | public class Main { |
使用var声明后,代码的写法可以变成如下的形式:
1 | public class Main { |
在上面的代码中,我们使用var代替了URL、URLConnection、Reader,提高了代码的可读性,也方便了开发。 但是在Java 10中,var变量不能在lambda表达式中声明,在Java 11中,解决了这个问题。现在,我们可以在lambda表达式中使用var,例如:
1 | Map<String, Object> map |
ZGC
ZGC 即 Z Garbage Collector(垃圾收集器或垃圾回收器),这应该是 Java 11 中最为瞩目的特性,没有之一。ZGC 是一个可伸缩的、低延迟的垃圾收集器,主要为了满足如下目标进行设计:
- GC 停顿时间不超过 10ms
- 即能处理几百 MB 的小堆,也能处理几个 TB 的大堆
- 应用吞吐能力不会下降超过 15%(与 G1 回收算法相比)
- 方便在此基础上引入新的 GC 特性和利用 colord
- 为 Load barriers 优化奠定基础
不过目前 ZGC 还处于实验阶段,目前只在 Linux/x64 上可用,如果有足够的需求,将来可能会增加对其他平台的支持。
作为实验性功能的 ZGC 将不会出现在 JDK 构建中,除非在编译时使用 configure 参数:–with-jvm-features=zgc 显式启用。编译完成之后,需要配置以下 JVM 参数,才能使用 ZGC,具体启动 ZGC 参数如下:
1 | -XX:+ UnlockExperimentalVMOptions -XX:+ UseZGC -Xmx10g |
ZGC 是一个并发收集器,必须要设置一个最大堆的大小,应用需要多大的堆,主要有下面几个考量:
- 对象的分配速率,要保证在 GC 的时候,堆中有足够的内存分配新对象。
- 一般来说,给 ZGC 的内存越多越好,但是也不能浪费内存,所以要找到一个平衡。
所有的Java 11 新特性参考链接
- 181: Nest-Based Access Control
- 309: Dynamic Class-File Constants
- 315: Improve Aarch64 Intrinsics
- 318: Epsilon: A No-Op Garbage Collector
- 320: Remove the Java EE and CORBA Modules
- 321: HTTP Client (Standard)
- 323: Local-Variable Syntax for Lambda Parameters
- 324: Key Agreement with Curve25519 and Curve448
- 327: Unicode 10
- 328: Flight Recorder
- 329: ChaCha20 and Poly1305 Cryptographic Algorithms
- 330: Launch Single-File Source-Code Programs
- 331: Low-Overhead Heap Profiling
- 332: Transport Layer Security (TLS) 1.3
- 333: ZGC: A Scalable Low-Latency Garbage Collector(Experimental)
- 335: Deprecate the Nashorn JavaScript Engine
- 336: Deprecate the Pack200 Tools and API