Java9新特性逐项解析,总有一项get到你的点
一、JDK 与 JRE 的关系
JDK :JavaDevelopmentKit (Java开发工具包)
JRE :JavaRuntimeEnvironment (Java运行环境)
说明:
JDK = JRE + 开发工具集(例如Javac编译工具等)
JRE = JVM + Java SE标准类库
二、JDK 8 的目录结构
说明:
bin 目录包含命令行开发和调试工具,如javac,jar和javadoc。
include目录包含在编译本地代码时使用的C/C++头文件
lib 目录包含JDK工具的几个JAR和其他类型的文件。 它有一个tools.jar文件,其中包含javac编译器的Java类
jre/bin 目录包含基本命令,如java命令。 在Windows平台上,它包含系统的运行时动态链接库(DLL)。
jre/lib 目录包含用户可编辑的配置文件,如.properties和.policy文件。包含几个JAR。 rt.jar文件包含运行时的Java类和资源文件。
三、JDK 9 的目录结构
说明:
没有名为jre的子目录
bin 目录包含所有命令。 在Windows平台上,它继续包含系统的运行时动态链接库。
conf 目录包含用户可编辑的配置文件,例如以前位于jrelib目录中的.properties和.policy文件
include 目录包含要在以前编译本地代码时使用的C/C++头文件。 它只存在于JDK中
jmods 目录包含JMOD格式的平台模块。 创建自定义运行时映像时需要它。 它只存在于JDK中
legal 目录包含法律声明
lib 目录包含非Windows平台上的动态链接本地库。 其子目录和文件不应由开发人员直接编辑或使用
四、Java9新增特性:
102: Process API Updates
进程操作API 升级,提升对操作系统进程的控制和管理。
新增的
java.lang.ProcessHandle
类丰富了对进程的操作,同时原有的
java.lang.Process
类的功能也被加强了。
在Java很早的版本中,提供了Process这样的API可以获得进程的一些信息,包括runtime,甚至是用它来执行当前主机的一些命令,但是请大家思考一个问题,你如何获得你当前Java运行程序的PID?很显然通过Process是无法获得的,需要借助于JMX才能得到,但是在这一次的增强中,你将会很轻松的得到这样的信息,我们来看一个简单的例子:
上面有大量的Optional,这是Java 8中的API,同样在Java 9中对其进行了增强。
已经获取到了JVM的进程,我们该如何将该进程优雅的停掉呢?下面的代码给出了答案
110: HTTP 2 Client
就目前而言,JDK提供的Http访问功能,几乎都需要依赖于HttpURLConnection,但是这个类大家在写代码的时候很少使用,我们一般都会选择Apache的Http Client,此次在Java 9的版本中引入了一个新的package:java.net.http,里面提供了对Http访问很好的支持,不仅支持Http1.1而且还支持HTTP2,以及WebSocket,据说性能可以超过Apache HttpClient,Netty,Jetty,简单的来看一个代码片段:
通过上面的一小段代码,我们也发现了Java 9对断言机制同样增加了一些增强,多说一些题外话,我们目前的系统中运行一个严重依赖于Hive beelineServer的程序,beeline server不是很稳定,经常出现卡顿,甚至假死,假死后也不回复的问题,这样就导致我们的程序也会出现卡顿,如果运维人员不对其进行清理,系统运行几个月之后会发现很多僵尸进程,于是增加一个获取当前JVM PID的功能,然后判断到超过给定的时间对其进行主动杀死,完全是程序内部的行为,但是获取PID就必须借助于JMX的动作,另外杀死它也必须借助于操作系统的命令,诸如kill这样的命令,显得非常的麻烦,但是Java 9的方式明显要优雅方便许多。
143: Improve Contended Locking
优化竞争锁的性能
能够改善程序运行时的多线程同步效率。
158: Unified JVM Logging
统一 JVM 日志
日志是解决问题的唯一有效途径:曾经很难知道导致JVM性能问题和导致JVM崩溃的根本原因。不同的JVM日志的碎片化和日志选项(例如:JVM组件对于日志使用的是不同的机制和规则),这使得JVM难以进行调试。
解决该问题最佳方法:对所有的JVM组件引入一个单一的系统,这些JVM组件支持细粒度的和易配置的JVM日志
165: Compiler Control
193: Variable Handles
操作内存,用来替代sun.misc.Unsafe。操作内存更安全,且性能相同或相似的等效sun.misc.unsafe操作。
在JDK 9中提供了一个新的包,叫做java.lang.invoke里面有一系列很重要的类比如VarHandler和MethodHandles,提供了类似于原子操作以及Unsafe操作的功能。
197: Segmented Code Cache
代码分段缓存
Java 9的另一个性能提升来自于JIT(Just-in-time)编译器。当某段代码被大量重复执行的时候, 虚拟机会把这段代码编译成机器码(native code)并储存在代码缓存里面, 继而通过访问缓存中不同分段的代码来提升编译器的效率。代码分段缓存机制将会提升许多方面的性能,如当JVM进行垃圾回收扫描的时候,就可以直接跳过永驻代码,从而提升效率
JDK 9 中的代码段在 Segmented Code Cache 的作用下,可以被更加细分,而且每个代码段还可以包括特定类型的编译代码,这个功能同样也有望提升 Java 9 性能。
这个特性一般不会在 Java 代码中直接使用,它通过对本地编译代码(即代码缓存)进行更好的组织,让 JRE 的运行效率有所提高。
198: Light-Weight JSON API
尽管目前有多种处理JSON的Java工具(如Google的Gson、阿里巴巴的FastJson、IBM的Json4J等),但JSON API是Java语言的一部分,轻量并且运用了Java 8的新特性。JSON API将放在java.util包里一起发布,这样,开发者就可以直接使用JDK而无需再引入第三方JSON工具包了
199: Smart Java Compilation, Phase Two
改进sjavac工具的稳定性和可移植性,使其可以更好地用于大型项目的构建。
智能Java编译工具(sjavac)的第一阶段始于JEP139这个项目, 用于在多核处理器情况下提升JDK的编译速度。如今,这个项目已经进入第二阶段即JEP199, 其目的是改进Java编译工具,并取代目前JDK编译工具javac,继而成为Java环境默认的通用的智能编译工具
200: The Modular JDK
Java 9中最重要的功能,毫无疑问就是模块化(Module),代码名字叫做Jigsaw(拉锯),这个拉锯项目拉了几年,终于要把庞大冗余的Java锯成一个个的Module,方便开发和部署。熟悉Java的同学,都知道JRE有一个超级大rt.jar(例如,Java 8的rt.jar中有65M),运行一个hello world,你也需要一个数百兆的JRE环境,如果在J2EE环境,情况将变得复杂无比
201: Modular Source Code
211: Elide Deprecation Warnings on Import Statements
212: Resolve Lint and Doclint Warnings
213: Milling Project Coin
接口的私有方法
Java 8中规定接口中的方法除了抽象方法之外,还可以定义静态方法和默认的方法。一定程度上,扩展了接口的功能,此时的接口更像是一个抽象类。
在Java 9中,接口更加的灵活和强大,连方法的访问权限修饰符都可以声明为private的了,此时方法将不会成为你对外暴露的API的一部分。
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)
交互式命令行
简称 JShell,方便对程序进行调试,以及快速检验 API 的可行性无须无须创建一个项目来学习 API,打开 JShell 即可。
在Java 8 出来的时候,很多人都喊着,这是要抢夺Scala等基于JVM动态语言的市场啊,其中有人给出了一个Java做不到的方向,那就是Scala可以当作脚本语言,Java可以么?很明显在此之前Java不行,ta也不具备动态性,但是此次Java 9 却让Java也可以像脚本语言一样来运行了,主要得益于JShell,我们来看一下这个演示
这是我们在Jshell这个控制台下运行,我们如何运行脚本文件呢?
223: New Version-String Scheme
224: HTML5 Javadoc
jdk 8 :生成的java帮助文档是在HTML 4 中,而HTML 4 已经是很久的标准了。
jdk 9 :javadoc的输出,现在符合兼容HTML 5 标准。
下图是java8 中生成的html页面,如果想要找到一些类文档,必须在google中搜索
下图是在java 9 中,添加了一个搜索框。
225: Javadoc Search
226: UTF-8 Property Files
属性文件支持 UTF-8 编码
ResourceBundle 的缺省编码问题一直是被吐槽的对象,非英文字符被转码为看不懂的形式,严重损害了代码的可读性。从 Java 9 开始,ResourceBundle 默认编码为 UTF-8。
227: Unicode 7.0
JDK9升级现有的平台APIs以支持Unicode标准的7.0版,支持Unicode的最新版本。
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
JDK 9 中附带了一个 Nashorn 的 parser API,它的目标是 Java 在本地 JVM 中实现轻量级高性能 JS runtime。这个新特性可以保障 Java 9 更好的融合 JavaScript 和 Java 的两方之力。
237: Linux/AArch64 Port
连接到Linux / AArch64的端口。
AArch64是ARM控股公司推出的新处理器体系结构。它与32位ARM处理器架构不同,实际上是一个完全的重新设计。它需要一个新的OpenJDK端口
238: Multi-Release JAR Files
当一个新版本的Java出现的时候,你的库用户要花费数年时间才会切换到这个新的版本。这就意味着库得去向后兼容你想要支持的最老的Java版本(许多情况下就是Java 6 或者 Java7)。这实际上意味着未来的很长一段时间,你都不能在库中运用Java 9所提供的新特性。幸运的是,多版本兼容jar功能能让你创建仅在特定版本的Java环境中运行库程序选择使用的class版本。
240: Remove the JVM TI hprof Agent
从JDK中删除高性能代理。
J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profiling,叫做HPROF。HPROF实际上是JVM中的一个native的库。该工具已被更好的替代品所取代。
241: Remove the jhat Tool
删除过时的jhat工具。
jhat是在JDK 6中基于Java . net帽子项目添加的。jhat是一个实验性的、不受支持的、过时的工具。高级堆可视化工具和分析器已经使用多年。
243: Java-Level JVM Compiler Interface
动态编译器
对于整个编程语言的发展,可能都具有非常重要的意义,虽然未必引起了广泛关注。目前 Graal Core API 已经被集成进入 Java 9,虽然还只是初始一小步,但是完全用 Java 语言来实现的可靠的、高性能的动态编译器,似乎不再是遥不可及。
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
G1 成为默认的垃圾收集器
G1 进一步减少了 GC 时的停顿时间(GC pause time),其实它从 JDK 8u40 开始就已经十分完善,足以作为默认的垃圾收集器了。
249: OCSP Stapling for TLS
250: Store Interned Strings in CDS Archives
251: Multi-Resolution Images
接口java.awt.image.MultiResolutionImage封装了一系列的不同分辨率图像到一个单独对象的API,我么可以根据给定的DPI 矩阵获取resolution-specific,看一下下面的代码片段:
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
Java 模块化-重大特性
该项目主要的目的是为更小的设备提供可伸缩性,改进 JDK 和 Java SE 的安全性,对大型应用的性能提升以及更易于构建。这个功能会使 JDK、run-time images 以及 Java 源代码等模块化,甚至开发者还可以创建自己的模块来简化代码
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
该特性为JVM的所有组件引入了一个通用的日志系统,提供了JVM日志的基础设施,你可以不用专门为了打印某些日志而添加一些专门的标签,只需要使用统一的log指令即可,比如:
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
G1中大量对象的附加测试
279: Improve Test-Failure Troubleshooting
自动收集诊断信息,以便在测试失败和超时的情况下进一步排除故障。
280: Indify String Concatenation
281: HotSpot C++ Unit-Test Framework
282: jlink: The Java Linker
Java连接器
连接器负责高层会话,如http会话。连接器框架组件,基于NIO开发,用于javaiis http服务器项目。
284: New HotSpot Build System
使用构建基础架构重写热点构建系统。
本项目的目标是用一个新的、简化得多的基于build - infra框架的构建系统替换当前的构建系统。更具体地说:
利用build - infra框架中提供的功能,最大限度地减少代码重复。
简化热点构建系统以提供更易于维护的代码库,并降低阈值以供将来改进。
285: Spin-Wait Hints
定义API以允许Java代码提示正在执行旋转循环,即自旋等待提示。
定义一个API,允许Java代码提示运行时系统它处于旋转循环中。API将是一个纯提示,不包含语义行为需求(例如,无操作是有效的实现)。允许JVM受益于在某些硬件平台上可能有用的自旋循环特定行为。在JDK中提供无操作实现和固有实现,并在至少一个主要硬件平台上演示执行优势。
287: SHA-3 Hash Algorithms
实现NIST FIPS 202中指定的SHA - 3加密散列函数(仅字节)。
SHA - 2发布于10多年前,虽然尚未证明对SHA - 2的重大攻击,但NIST认为需要一种不同的加密散列函数来替代SHA - 2。九年来,SHA - 3是NIST利用公开竞争和审查过程开发的第一个加密哈希算法。FIPS 202 " SHA - 3标准:基于排列的散列和可扩展输出函数"于2015年8月作为标准定稿。当FIPS 202还是草稿时,诸如BouncyCastle之类的加密供应商开始支持SHA - 3。Solaris还将在即将发布的Solaris 12.0版本中支持SHA - 3。由于哈希函数在安全应用程序中广泛使用,并且其他供应商已经添加了SHA - 3实现,因此在JDK中为SHA - 3提供支持非常重要。
288: Disable SHA-1 Certificates
通过提供更灵活的机制来禁用具有基于SHA - 1签名的x . 509证书链,改进了JDK的安全配置。
目标不是禁用SHA - 1证书的所有用法。只有通过CertPathValidator和CertPathBuilder API的PKIX实现以及TrustManagerFactory API的SunX509和PKIX实现验证的X.509证书链才受限制。其他用途(解析等)。)中的证书不受影响。CertPathValidator、CertPathBuilder和TrustManagerFactory的第三方实现直接负责实施它们自己的限制。
基于SHA - 1的数字签名算法的使用由于冲突攻击的风险而日益成为安全问题。NIST在SP 800 - 57第1部分中建议不再使用SHA - 1对数据应用数字签名。CA / Browser论坛对公众信任的SSL证书的基线要求规定,自2016年1月1日起,证书颁发机构不得使用SHA - 1颁发任何从属CA或订户证书。其他软件供应商(谷歌、微软、Mozilla、苹果)已经公布了在证书中对SHA - 1进行贬值的计划。在JDK中,x . 509证书链用于验证TLS中的服务器和客户端以及验证签名代码的完整性和作者
289: Deprecate the Applet API
Applet API 被标记为为过时。
要在web浏览器中运行Java小程序,需要使用浏览器插件。然而,截至2015年底,许多浏览器供应商要么已经取消了插件支持,要么宣布了取消插件支持的时间表。一旦浏览器插件消失,就没有理由使用Applet API。
290: Filter Incoming Serialization Data
291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
Java 9 或将放弃 CMS(并发标记清除垃圾收集器)
取消对CMS的支持,然后删除CMS代码,或者至少更彻底地分离CMS代码,将减少GC代码库的维护负担,并加快新的开发。从长远来看,G1垃圾收集器将取代CMS的大多数用途。
新版本未指定将删除CMS支持的主要版本。何时执行此操作,取决于G1收集器在多大程度上被证明是CMS的合适替代品。同时,鼓励CMS用户迁移到G1收集器( - XX : + UseG1GC )。
但是从经验来看,很多 Java 应用选择的是 CMS+ParNew,而且很多应用针对 CMS 的行为做了优化。现在宣布去掉 CMS,或许还为时过早。
292: Implement Selected ECMAScript 6 Features in Nashorn
ECMAScript 6于2015年6月发布。到目前为止,还没有一个JavaScript引擎提供对ES6的完整支持,但是包括Google V8、Mozilla蜘蛛猴和JavaScript core在内的主要引擎最近在实现ES6方面取得了重大进展。
Nashorn 项目在 JDK 9 中得到改进,它为 Java 提供轻量级的 Javascript 运行时。Nashorn 项目跟随 Netscape 的 Rhino 项目,目的是为了在 Java 中实现一个高性能但轻量级的 Javascript 运行时。Nashorn 项目使得 Java 应用能够嵌入 Javascript。它在 JDK 8 中为 Java 提供一个 Javascript 引擎。
JDK 9 包含一个用来解析Nashorn 的ECMAScript 语法树的API。这个 API 使得 IDE 和服务端框架不需要依赖 Nashorn 项目的内部实现类,就能够分析 ECMAScript 代码。
294: Linux/s390x Port
s390x (也称为“系统z”或“z /体系结构”)是由IBM开发和支持的大型机体系结构。包括Ubuntu、RHEL / Fedora和SuSE在内的几个Linux发行版在s390上运行。
目前的云部署,包括TomEE、Cassandra、Spark、Hadoop和Neo4j等软件包,严重依赖Java。因为大多数软件包都是开源的,所以它们在OpenJDK上运行得最好,而OpenJDK目前对Linux / s390x不可用。
目前,零端口可用于在Linux / s390x上运行JDK,但速度很慢(因为它只使用旧的、弃用的c++解释器),并且测试不太好。它不是运行应用程序服务器或用Java编写的数据库应用程序等工作负载的真正替代方案。
IBM的Linux开发工具包也可用于Linux / s390x,但它目前不是开源的,Java应用程序通常需要一些配置/调优才能与它一起运行。此外,它不能用于测试即将发布的Java版本的新功能,因为它仅在JDK本身是GA之后发布。
SAP有一个完整的(即模板解释器、C1和C2 JIT )和经过认证的( Java SE 1.4 - 8 ) s390x端口,已在生产中使用多年。
295: Ahead-of-Time Compilation
AOT 编译
JIT(Just-in-time)编译器可以在运行时将热点编译成本地代码,速度很快。但是 Java 项目现在变得很大很复杂,因此 JIT 编译器需要花费较长时间才能热身完,而且有些 Java 方法还没法编译,性能方面也会下降。AoT 编译就是为了解决这些问题而生的。
AOT 编译作为实验特性被引入进来,开发者可以利用新的 jaotc 工具将重点代码转换成类似类库一样的文件,这样会大大降低启动开销。
这个功能使得 Java 应用在被虚拟机启动之前能够先将 Java 类编译为原生代码。此功能旨在改进小型和大型应用程序的启动时间,同时对峰值性能的影响很小。
该功能目前仍处于试验阶段,希望java10能有一个更稳定的版本。
jaotc详见:http://blog.csdn.net/hj7jay/article/details/54580038
297: Unified arm32/arm64 Port
arm 32和arm 64的统一热点端口集成到JDK中。
为arm 32和arm 64提供了C1和C2支持,使其与其他体系结构保持一致。代码已合并到aarch32项目区域中单独存储库中的JDK 9树中。
Oracle打算开放ARM端口的消息已于2016年8月23日在aarch 32邮件列表中公布,并且aarch 32邮件列表中有几个讨论线索。
298: Remove Demos and Samples
删除过时和未维护的演示和示例,其目的不是创建新的或替换的演示和示例。
JDK / src / demo和JDK / src / sample中的大多数现有演示和示例都已过时且未维护,因此对处理JDK本身的开发人员或更广泛的Java社区都不再有用。它们的源代码不再代表Java编程语言和Java SE平台的最新使用情况,也没有更新它们的计划。更好的示例代码可以从许多其他来源获得,例如在更广泛的社区中发布的许多文章、书籍和演示文稿中
299: Reorganize Documentation
重新组织JDK文档的结构,包括源存储库和生成的文档。
目标
为生成的“文档”映像正式定义一个组织,包括API规范、手册页(可视为工具规范)和其他JDK规范。
将javadoc工具生成的当前20多组文档合并到JDK映像的单个API规范集合中。
为源存储库中存在的非API规范定义一个组织,以便根据需要随源代码一起更新这些规范,并可以轻松地将其包括在生成的“文档”映像中。
推荐相关文章:
《Java8最值得学习的新特性:Lambda,Stream API》
《java9 150多项新特性,大改版,内附源码,实战解析,收藏!》
参考:
http://www.infoq.com/cn/articles/is-java-out-of-date
http://blog.csdn.net/hj7jay/article/details/54580038