前言
在Java 9发布之后,Java 10很快就出现了。与之前的版本不同,Java 10没有那么多令人兴奋的特性,但是它仍然有一些重要的更新,这些更新将改变我们编写代码的方式,以及其他未来的Java版本。
正文
局部变量类型推断(Local Variable Type Inference)
Java现在有了var
样式声明。它允许我们在不指定类型的情况下声明局部变量。变量的类型将从实际创建的对象的类型中推断出来。
这个特性对Java 10开发人员来说可以说是唯一的特性,因为其它Java 10的特性更新离我们编码较远。
如下:
1 | var str = "Hello world"; |
在上面的例子中,两个语句是等价的。在第一个语句中,str的类型由赋值类型决定,赋值类型为字符串类型。
想了解更多有关内容,可以阅读这篇文章Java 10 局部变量类型推断。
基于时间的发布版本(Time-Based Release Versioning)
从Java 10开始,Oracle已经采用了基于时间的版本字符串模式。版本号的新格式为:
1 | $FEATURE.$INTERIM.$UPDATE.$PATCH |
与旧版本不同的是,基于时间的新版本不会延迟发布,新功能将每六个月发布一次,对新版本中可以发布哪些功能没有限制。
还有长期发行版本(LTS)。主要面向企业客户。LTS版本的产品将由Oracle公司提供卓越和持续的支持。此外,这些版本的更新将至少在三年内可用。
关于该部分的更多内容,可以查看这篇文章Java 10 基于时间的发布版本.
垃圾收集器接口(Garbage-Collector Interface)
在早期的JDK结构中,组成垃圾收集器(GC)实现的组件分散在代码库的各个部分。它在Java 10中进行了变化。现在,它是JVM源代码中的一个干净的接口,允许快速、轻松地集成替代收集器。它将改进不同垃圾收集器的源代码隔离。
这是一次非常重要的重构,以使得垃圾收集器可以适应过去现在及未来的需要。
G1的并行Full GC(Parallel Full GC for G1)
Java 9引入了 G1(garbage first) 垃圾收集器。G1垃圾收集器的设计是为了避免Full GC,但当并发收集不能足够快地回收内存时。有了这个更改,就会发生 Full GC。
G1 Full GC 实现使用的是单线程 标记-清除-压缩(mark-sweep-compact) 算法。这个更改将并行化 标记-清除-压缩(mark-sweep-compact) 算法,并使用相同数量的线程。当收集的并发线程不能足够快地恢复内存时,将会触发G1 Full GC。
线程的数量可以通过-XX:ParallelGCThreads
选项进行控制。
可选内存设备上的堆分配(Heap Allocation on Alternative Memory Devices)
此更改的目的是使HotSpot VM
能够在用户指定的其他内存设备(如NV-DIMM)上分配Java对象堆。
要在这样的内存中分配堆,我们可以添加一个新选项:-XX:AllocateHeapAt=<path>
。此选项将采用到文件系统的路径,并使用内存映射来实现在内存设备上分配对象堆的期望结果。现有的堆相关参数(如-Xmx
、-Xms
等)和垃圾收集相关参数将继续工作。
JDK 分支整合(Consolidate the JDK Forest into a Single Repository)
为了简化和简化开发,JDK 分支的许多存储库被合并到一个单独的存储库中。
在JDK 9中有八个repos
: root
、corba
、hotspot
、jaxp
、jaxws
、JDK
、langtools
和nashorn
。在合并后,Java模块的代码在一个顶级src
目录下。
例如,之前JDK分支有一些基于模块的目录,比如:
1 | $ROOT/jdk/src/java.base |
整合后,它们现在变为这样:
1 | $ROOT/src/java.base |
应用数据共享(Application Class-Data Sharing)
该特性的目标是改进启动占用空间,扩展现有的类数据共享(“CDS”)特性,允许将应用程序类放在共享归档中。
在JDK 5中引入的类数据共享允许将一组类预先处理为共享的存档文件,然后在运行时对这些文件进行内存映射,以减少启动时间。当多个jvm共享相同的归档文件时,它还可以减少动态内存占用。
目前CDS只允许引导类加载器加载存档的类。应用程序CDS允许内置的系统类装入器、内置的平台类装入器和自定义类装入器装入归档的类。
指定-XX:+UseAppCDS
命令行选项,以便为系统类装入器、平台类装入器和其他用户定义的类装入器启用类数据共享。
Unicode语言标记扩展(Additional Unicode Language-Tag Extensions)
它的目标是增强java.util.Locale
和相关api来实现BCP 47语言标记的额外Unicode扩展。
对BCP 47语言标记的支持最初是在Java SE 7中添加的,对Unicode区域设置扩展的支持仅限于日历和数字。这个JEP将在相关的JDK类中实现最新LDML规范中指定的更多扩展。
这个JEP将增加对以下附加扩展的支持:
- cu (currency type)
- fw (first day of week)
- rg (region override)
- tz (time zone)
修改的相关API有:
1 | java.text.DateFormat::get*Instance |
根证书(Root Certificates)
作为JDK的一部分,cacerts密钥存储库旨在包含一组根证书,这些根证书可用于在各种安全协议中使用的证书链中建立信任。但是,JDK源代码中的cacerts密钥库目前是空的。
cacerts密钥存储库将使用一组由Oracle的Java SE根CA程序签名颁发的根证书。许多供应商已经签署了所需的协议,并为每个供应商提供了将包含的根证书列表。那些没有签署协议的国家将不在此列。那些需要较长时间处理的将包含在下一个版本中。
这也意味着Oracle和Open JDK的二进制文件在功能上是相同的。关键的安全组件,比如TLS,将在OpenJDK构建中默认使用。
基于Java的JIT编译器(Experimental Java-Based JIT Compiler)
该特性使基于Java的JIT编译器 Graal 能够作为Linux/x64平台上的实验性JIT编译器使用。Graal将使用JDK 9中引入的JVM编译器接口(JVMCI)。Graal已经在JDK中了,所以启用它作为实验性的JIT主要是测试和调试工作。
要启用Graal作为JIT编译器,请在Java命令行上使用以下选项:
1 | -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler |
Graal是Java中对JIT编译器的完全重写。以前的JIT编译器是用c++编写的。
线程本地”握手”(Thread-Local Handshakes)
这个JEP通过在不执行全局VM安全点的情况下在应用程序线程上执行回调,为改进VM性能奠定了基础。这意味着JVM可以停止单个线程,而不是全部。
线程本地握手将首先在x64和SPARC上实现。其他平台将退回到正常的安全点。新选项-XX:ThreadLocalHandshakes
(默认值为true)允许用户在支持的平台上选择正常的安全点。
移除头文件生成工具(Remove the Native-Header Generation Tool)
它将从JDK中删除javah
工具,这是一个在编译JNI代码时生成头文件的独立工具,因为这可以通过javac
完成。
这是另一个Java 10特性,侧重于管理。
新增的API和参数(New Added APIs and Options)
Java 10里新增了73个API,我们来看下:
API | DESCRIPTION |
---|---|
Optional.orElseThrow() | 一个新的方法orElseThrow被添加到这个可选的类中。它是现有get方法的同义词,现在是首选的替代方法 |
List.copyOf, Set.copyOf, and Map.copyOf | 这些方法从现有实例创建新的集合实例 |
Collectors.toUnmodifiableList, Collectors.toUnmodifiableSet, Collectors.toUnmodifiableMap | 这些方法允许将流的元素收集到不可修改的集合中 |
–jdk.disableLastUsageTracking | 禁用对正在运行的VM的JRE最后一次使用情况跟踪 |
–add-stylesheet | 支持在生成的文档中使用多个样式表 |
–main-stylesheet | 以帮助区分主样式表和其他样式表 |
@summary Tag | 添加以显式指定用作API描述摘要的文本。默认情况下,API描述的摘要是从第一句话推断出来的 |
删除的API和参数(Removed APIs and Options)
API | DESCRIPTION |
---|---|
LookAndFeels | |
Runtime.getLocalizedInputStream, Runtime.getLocalizedOutputStream | 过时的国际化机制的一部分,没有实际用途 |
RMI Server-Side Multiplex Protocol Support | JDK 9被禁用,现在已被删除 |
Common DOM APIs | com.sun.java.browser.plugin2.DOM 和sun.plugin.dom.DOMObject 现已被删除,应用可以使用netscape.javascript.JSObject 去操作DOM |
FlatProfiler | JDK 9已弃用,目前已删除 |
-Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads,-Xusealtsigs | 这几项参数均被移除 |
policytool | policytool安全工具已从JDK中删除。 |
弃用com.sun.security.auth.** | 下面的class已被删除:com.sun.security.auth.PolicyFile, com.sun.security.auth.SolarisNumericGroupPrincipal,com.sun.security.auth.SolarisNumericUserPrincipal,com.sun.security.auth.SolarisPrincipal,com.sun.security.auth.X500Principal,com.sun.security.auth.module.SolarisLoginModule,com.sun.security.auth.module.SolarisSystem |