Java 9终于来了,新功能按得住程序员苦等一年的火气吗?

Java的发展真的越来越快了,在Java 9正式发布之前,我们可以使用它的SNAPSHOT版本,先来体验一下Java 9 有哪些新的特性,下面的清单来自于官方文档,看着似乎很多,但是真正具有颠覆意

本文最后更新时间:  2023-05-03 00:43:57

Java的发展真的越来越快了,在Java 9正式发布之前,我们可以使用它的SNAPSHOT版本,先来体验一下Java 9 有哪些新的特性,下面的清单来自于官方文档,看着似乎很多,但是真正具有颠覆意义的其实就是Module System,其余很多主要是一些新的feature增加,还有一些功能的加强,在本篇文章中,我们将介绍一下主要的几个,不会一一去说,资料也不多,所以我想说也没的说,另外Java 8 是我认为迄今为止Java 最大的一次变化,不光是特性的增加,更多的是编程风格的转变,

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

8215: 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 Versions2

48: Make G1 the Default Garbage Collector

249: OCSP Stapling for TLS250: 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 API260: 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.0268: 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 G

1279: 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 Hints287: SHA-3 Hash Algorithms

288: Disable SHA-1 Certificates

289: Deprecate the Applet API

290: Filter Incoming Serialization Data

292: Implement Selected ECMAScript 6 Features in Nashorn

294: Linux/s

390x Port295: Ahead-of-Time Compilation

1. Modular System – Jigsaw Project

该特性是Java 9 最大的一个特性,Java 9起初的代号就叫Jigsaw,最近被更改为Modularity,Modularity提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节,Java提供该功能的主要的动机在于,减少内存的开销,我们大家都知道,在JVM启动的时候,至少会有30~60MB的内存加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class,那么JVM是如何知道需要加载那些class的呢?这就是在Java 9 中引入的一个新的文件module.java我们大致来看一下一个例子(module-info.java)

[java] view plain copy print?

module com.baeldung.java9.modules.car {

requires com.baeldung.java9.modules.engines;

exports com.baeldung.java9.modules.car.handling;

}

关于更多Java 9 模块编程的内容请参考一本书:《Java 9 Modularity》 里面讲的比较详细,介绍了当前Java对jar之间以来的管理是多么的混乱,引入modularity之后的改变会是很明显的差别。

2. A New Http Client

就目前而言,JDK提供的Http访问功能,几乎都需要依赖于HttpURLConnection,但是这个类大家在写代码的时候很少使用,我们一般都会选择Apache的Http Client,此次在Java 9的版本中引入了一个新的package:java.net.http,里面提供了对Http访问很好的支持,不仅支持Http1.1而且还支持HTTP2,以及WebSocket,据说性能可以超过Apache HttpClient,Netty,Jetty,简单的来看一个代码片段

[java] view plain copy print?

URI httpURI = new URI(\"http://www.94jiankang.com\");

HttpRequest request = HttpRequest.create(httpURI).GET();

HttpResponse response = request.response();

String responseBody = response.body(HttpResponse.asString());

3. Process API Enhance

在Java很早的版本中,提供了Process这样的API可以获得进程的一些信息,包括runtime,甚至是用它来执行当前主机的一些命令,但是请大家思考一个问题,你如何获得你当前Java运行程序的PID?很显然通过Process是无法获得的,需要借助于JMX才能得到,但是在这一次的增强中,你将会很轻松的得到这样的信息,我们来看一个简单的例子

[java] view plain copy print?

ProcessHandle self = ProcessHandle.current();

long PID = self.getPid();

ProcessHandle.Info procInfo = self.info();

Optional<String[]> args = procInfo.arguments();

Optional<String> cmd = procInfo.commandLine();

Optional<Instant> startTime = procInfo.startInstant();

Optional<Duration> cpuUsage = procInfo.totalCpuDuration();

上面有大量的Optional,这是Java 8中的API,同样在Java 9中对其进行了增强,本人在Java 8实战视频中对Optional API进行了源码级别的剖析,感兴趣的一定要去看看。

已经获取到了JVM的进程,我们该如何将该进程优雅的停掉呢?下面的代码给出了答案

[java] view plain copy print?

childProc = ProcessHandle.current().children();

childProc.forEach(procHandle -> {

assertTrue(\"Could not kill process \" + procHandle.getPid(), procHandle.destroy());

});

通过上面的一小段代码,我们也发现了Java 9对断言机制同样增加了一些增强,多说一些题外话,我们目前的系统中运行一个严重依赖于Hive beelineServer的程序,beeline server不是很稳定,经常出现卡顿,甚至假死,假死后也不回复的问题,这样就导致我们的程序也会出现卡顿,如果运维人员不对其进行清理,系统运行几个月之后会发现很多僵尸进程,于是增加一个获取当前JVM PID的功能,然后判断到超过给定的时间对其进行主动杀死,完全是程序内部的行为,但是获取PID就必须借助于JMX的动作,另外杀死它也必须借助于操作系统的命令,诸如kill这样的命令,显得非常的麻烦,但是Java 9的方式明显要优雅方便许多。

4. Try-With-Resources的改变

我们都知道,Try-With-Resources是从JDK 7 中引入的一项重要特征,只要接口继承了Closable就可以使用Try-With-Resources,减少finally语句块的编写,在Java 9 中会更加的方便这一特征

[java] view plain copy print?

MyAutoCloseable mac = new MyAutoCloseable();

try (mac) {

// do some stuff with mac

}

try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {

// do some stuff with finalCloseable

} catch (Exception ex) { }

我们的Closeable完全不用写在try()中。

5. Diamond Operator Extension

[java] view plain copy print?

FooClass<Integer> fc = new FooClass<>(1) { // anonymous inner class

};

FooClass<? extends Integer> fc0 = new FooClass<>(1) {

// anonymous inner class

};

FooClass<?> fc1 = new FooClass<>(1) { // anonymous inner class

};

6. Interface Private Method

[java] view plain copy print?

interface InterfaceWithPrivateMethods {

private static String staticPrivate() {

return \"static private\";

}

private String instancePrivate() {

return \"instance private\";

}

default void check() {

String result = staticPrivate();

InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {

// anonymous class

};

result = pvt.instancePrivate();

}

}}

该特性完全是为了Java 8中default方法和static方法服务的。

7. JShell Command Line Tool

在Java 8 出来的时候,很多人都喊着,这是要抢夺Scala等基于JVM动态语言的市场啊,其中有人给出了一个Java做不到的方向,那就是Scala可以当作脚本语言,Java可以么?很明显在此之前Java不行,ta也不具备动态性,但是此次Java 9 却让Java也可以像脚本语言一样来运行了,主要得益于JShell,我们来看一下这个演示

[java] view plain copy print?

jdk-9\bin>jshell.exe

| Welcome to JShell -- Version 9

| For an introduction type: /help intro

jshell> \"This is my long string. I want a part of it\".substring(8,19);

$5 ==> \"my long string\"

这是我们在Jshell这个控制台下运行,我们如何运行脚本文件呢?

[java] view plain copy print?

jshell> /save c:\develop\JShell_hello_world.txt

jshell> /open c:\develop\JShell_hello_world.txt

Hello JShell!

8.JCMD Sub-Commands

记得在Java 8中,放弃了Jhat这个命令,但是很快在Java 9中增加了一些新的命令,比如我们要介绍到的jcmd,借助它你可以很好的看到类之间的依赖关系

[java] view plain copy print?

jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket

14056:

java.lang.Object/null

|--java.net.Socket/null

| implements java.io.Closeable/null (declared intf)

| implements java.lang.AutoCloseable/null (inherited intf)

| |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket

| | implements java.lang.AutoCloseable/null (inherited intf)

| | implements java.io.Closeable/null (inherited intf)

| |--javax.net.ssl.SSLSocket/null

| | implements java.lang.AutoCloseable/null (inherited intf)

| | implements java.io.Closeable/null (inherited intf)

9.Мulti-Resolution Image API

接口java.awt.image.MultiResolutionImage封装了一系列的不同分辨率图像到一个单独对象的API,我么可以根据给定的DPI 矩阵获取resolution-specific,看一下下面的代码片段

[java] view plain copy print?

BufferedImage[] resolutionVariants = ....

MultiResolutionImage bmrImage

= new BaseMultiResolutionImage(baseIndex, resolutionVariants);

Image testRVImage = bmrImage.getResolutionVariant(16, 16);

温馨提示:内容均由网友自行发布提供,仅用于学习交流,如有版权问题,请联系我们。