JDK9你必须了解的新特性

Flow

JDK 9 Flow 是JDK对Reactive Stream (响应式流/反应流) 的实现,Reactive Stream是一套基于发布/订阅模式的数据处理规范。

响应式(Reactive Stream) 规范定义了如下四个接口:

Subscription 接口定义了连接发布者和订阅者的方法
Publisher 接口定义了发布者的方法
Subscriber 接口定义了订阅者的方法
Processor<T,R> 接口定义了处理器


HTTP2 Client

JDK之前 HttpURLConnection API 有许多问题

  • URLConnection API 设计了许多的协议,现在基本上都过时了。
  • 设计API时还没有HTTP1.0并且设计的太过抽象
  • 很难用并且许多操作没有文档
  • 它只有阻塞模式,也就是一个线程只能同时处理一个请求和响应
  • 很难维护

所以基本上都是使用Apache HttpClient等外部库。

新的Client简单易用,并提供事件通知,比如header received,response body received等等。JDK9的实现不是通过Callback的形式,而是使用了CompletableFuture返回,内部是使用响应式编程实现(Flow),性能与内存消耗上在设计上至少与Netty,Apache HttpClient持平。

发送 GET 请求并打印接收到的 Response body

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("http://openjdk.java.net/"))
      .build();
      
client.sendAsync(request, BodyHandlers.ofString())
      .thenApply(HttpResponse::body)
      .thenAccept(System.out::println)
      .join();

Variable Handles

在JDK9之前将一个计数字段原子的自增有以下几种方式:

使用AtomicInteger,但是AtomicInteger 会增加额外的空间和管理间接的附加的并发问题。

使用AtomicXXXFieldUpdater,它虽然不会增加额外的空间但是它的性能没有直接操作它自己本身快。

使用不安全的sun.misc.Unsafe,由于是底层操作所以性能很高,由于这个原因也让它使用越来越广泛,但是使用Unsafe也就损失了移植性和安全性。

JDK为了解决这个问题,在JDK9推出了VarHandle,它提供了一系列标准的内存屏障操作,用于更细粒度的控制指令排序,在安全性、易用性、性能等方面都要优于现有的API。

在JDK9+后,J.U.C下的所有使用Unsafe的地方全都使用VarHandle进行了替换和重写。


Modular Run-Time Images -- Project Jigsaw

JDK9以前的rt.jar包含非常多的东西,从JDK1.0的211个Class到JDK8的数千个Class,JDK新增了很多功能,进而更快地开发我们的代码。问题是这些Class变为了一个整体,这4500个Class都在一个文件中,但是没有人会在一个应用程序中将这4500个Class都使用到。

模块化就是将这些Class分类进行管理,为此 OpenJDK设计了75个module,在Oracle中更多。通过将rt.jar拆分成更易管理的部分,以使你可以专门为自己的应用程序量身定做run-time,仅包含自己需要的modules,以此是的run-time最小化。在rt.jar中处理4500个Class外还有一些private的Class,它不应该被开发人员使用,其中最臭名昭著的就是sun.misc.Unsafe,很多框架开发人员,会通过这些东西来提升框架的性能和使用底层功能。

模块化后的好处

  • 强封装

模块显示地选择向其他模块公开的内容,从而防止内部实现细节意外依赖。

公开的接口需要显示配置,未配置的接口无论通过那种方式都无法在其他模块访问。

从而防止模块之间发生意外或不必要的耦合。

  • 安全性

在JVM最深层次上执行强封装,从而减少Java运行时的攻击面,同时无法获得对敏感内部类的反射访问。

  • 优化

由于模块系统知道哪些模块是在一起的,包括平台模块,因此在JVM启动期间不需要考虑其他代码。


jlink

使用jlink缩减你的run-time,受其真正影响最重要的领域之一就是微服务,因为它只包含你需要的module,它比完整的java run-time小得多,一个完整的有几百兆,但是使用jlink你可以将它缩小到10M左右。

使用jlink可以使打出的jar包更小,受攻击面更小,也就更安全。


Compact Strings

采用更节省空间的字符串内部表示。

在JDK9之前使用char数组来存放字符,也就是每个字符需要2Byte(16bit),Oracle的开发人员进行了一些统计,发现堆中String类型占了很大的比例,而绝大部分String对象只包含Latin-1字符。

Latin-1

ISO Latin-1字符集是Unicode字符集的一个子集,对应于IE4+中Unicode字符指令表的前256个条目。下面表格中详细提供了每个字符及字符的十进制编码和HTML已命名实体。其中Unicode字符为双字节16位,可以表示任何一种语言符号;而Latin-1字符集是单字节8位,只能够表示英文和西欧字符


不可变集合工厂方法

Java 9增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合。

List strs = List.of("Hello", "World");
List strs List.of(1, 2, 3);

移除了CMS垃圾回收器


将G1设定为默认的垃圾回收器

由于GC的默认实现类被替换为G1,所以废弃的GC选项已被移除。


统一 JVM 日志

Java 9 中 ,JVM 有了统一的日志记录系统,可以使用新的命令行选项-Xlog 来控制 JVM 上 所有组件的日志记录。该日志记录系统可以设置输出的日志消息的标签、级别、修饰符和输出目标等。


私有接口方法

Java 8 为我们提供了接口的默认方法和静态方法,接口也可以包含行为,而不仅仅是方法定义(使用default修饰的方法可以在接口中实现,而不是只能声明);

Java9中对接口进行了第二次的扩展,默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。如果私有方法是静态的,那这个方法就属于这个接口的。并且没有静态的私有方法只能被在接口中的实例调用。


增强的 try-with-resources

在JDK7中如果有多个资源需要关闭,则需要在try中写多个。

try (BufferedReader bufferReader0 = new BufferedReader(...);
BufferedReader bufferReader1 = new BufferedReader(...)){ 
     return bufferReader0.readLine();
}

JDK9对其进行了增强

BufferedReader bufferReader0 = new BufferedReader(...);
BufferedReader bufferReader1 = new BufferedReader(...);
try (bufferReader0; bufferReader1){ 
     System.out.println(br1.readLine() + br2.readLine()); 
}

本文只是针对平时开发可能会用到的特性进行了介绍,完整的JDK9一共更新九十多个新特性。

完整的新特性列表

102: Process API Updates
110: HTTP 2 Client
143: Improve Contended Locking
158: Unified JVM Logging
165: Compiler Control
193: Variable Handles
197: Segmented Code Cache
199: Smart Java Compilation, Phase Two
200: The Modular JDK
201: Modular Source Code
211: Elide Deprecation Warnings on Import Statements
212: Resolve Lint and Doclint Warnings
213: Milling Project Coin
214: Remove GC Combinations Deprecated in JDK 8
215: Tiered Attribution for javac
216: Process Import Statements Correctly
217: Annotations Pipeline 2.0
219: Datagram Transport Layer Security (DTLS)
220: Modular Run-Time Images
221: Simplified Doclet API
222: jshell: The Java Shell (Read-Eval-Print Loop)
223: New Version-String Scheme
224: HTML5 Javadoc
225: Javadoc Search
226: UTF-8 Property Files
227: Unicode 7.0
228: Add More Diagnostic Commands
229: Create PKCS12 Keystores by Default
231: Remove Launch-Time JRE Version Selection
232: Improve Secure Application Performance
233: Generate Run-Time Compiler Tests Automatically
235: Test Class-File Attributes Generated by javac
236: Parser API for Nashorn
237: Linux/AArch64 Port
238: Multi-Release JAR Files
240: Remove the JVM TI hprof Agent
241: Remove the jhat Tool
243: Java-Level JVM Compiler Interface
244: TLS Application-Layer Protocol Negotiation Extension
245: Validate JVM Command-Line Flag Arguments
246: Leverage CPU Instructions for GHASH and RSA
247: Compile for Older Platform Versions
248: Make G1 the Default Garbage Collector
249: OCSP Stapling for TLS
250: Store Interned Strings in CDS Archives
251: Multi-Resolution Images
252: Use CLDR Locale Data by Default
253: Prepare JavaFX UI Controls & CSS APIs for Modularization
254: Compact Strings
255: Merge Selected Xerces 2.11.0 Updates into JAXP
256: BeanInfo Annotations
257: Update JavaFX/Media to Newer Version of GStreamer
258: HarfBuzz Font-Layout Engine
259: Stack-Walking API
260: Encapsulate Most Internal APIs
261: Module System
262: TIFF Image I/O
263: HiDPI Graphics on Windows and Linux
264: Platform Logging API and Service
265: Marlin Graphics Renderer
266: More Concurrency Updates
267: Unicode 8.0
268: XML Catalogs
269: Convenience Factory Methods for Collections
270: Reserved Stack Areas for Critical Sections
271: Unified GC Logging
272: Platform-Specific Desktop Features
273: DRBG-Based SecureRandom Implementations
274: Enhanced Method Handles
275: Modular Java Application Packaging
276: Dynamic Linking of Language-Defined Object Models
277: Enhanced Deprecation
278: Additional Tests for Humongous Objects in G1
279: Improve Test-Failure Troubleshooting
280: Indify String Concatenation
281: HotSpot C++ Unit-Test Framework
282: jlink: The Java Linker
283: Enable GTK 3 on Linux
284: New HotSpot Build System
285: Spin-Wait Hints
287: SHA-3 Hash Algorithms
288: Disable SHA-1 Certificates
289: Deprecate the Applet API
290: Filter Incoming Serialization Data
291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
292: Implement Selected ECMAScript 6 Features in Nashorn
294: Linux/s390x Port
295: Ahead-of-Time Compilation
297: Unified arm32/arm64 Port
298: Remove Demos and Samples
299: Reorganize Documentation

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值