Java10特性和增强功能插图

在Java9发布之后,Java10很快就出现了。与以前的版本不同,Java10没有那么多令人兴奋的特性,但是它几乎没有什么重要的更新,这些更新将改变您的编码方式,以及其他未来的Java版本。

JEP 286:局部变量类型推断

Java现在有var样式的声明。它允许您声明局部变量而不指定其类型。变量的类型将从创建的实际对象的类型推断出来。它声称是JDK10中开发人员的唯一真正特性。例如:

var str = "Hello world";
  
//or
  
String str = "Hello world";

在上面的例子中,这两个语句是等价的。在第一条语句中,str的类型是由赋值类型决定的,而赋值类型是String类型。

JEP 322:基于时间的版本控制

从Java10开始,Oracle采用了基于时间的版本字符串方案。版本号的新格式为:

$FEATURE.$INTERIM.$UPDATE.$PATCH

与旧版本不同的是,新的基于时间的版本不会延迟,功能将每六个月发布一次,对发布的功能没有限制。

还有长期版本(LTS)。主要面向企业客户。LTS版本的产品将提供甲骨文卓越和持续的支持,并将每3年瞄准一次。此外,这些版本的更新将至少持续三年。

JEP 304:垃圾收集器接口

在早期的JDK结构中,组成垃圾收集器(GC)实现的组件分散在代码库的各个部分。它在Java10中被改变了。现在,它是JVM源代码中一个干净的接口,允许快速轻松地集成其他收集器。它将改进不同垃圾收集器的源代码隔离。

这纯粹是重构。以前工作过的一切都需要以后再工作,性能不应该倒退。

JEP 307:G1并行全GC

Java9引入了G1(垃圾优先)垃圾收集器。G1垃圾收集器旨在避免完全收集,但是当并发收集不能足够快地回收内存时。通过此更改,将发生完全GC的回退。

G1的完整GC的当前实现使用单线程标记扫描压缩算法。此更改将并行化标记扫描压缩算法,并使用相同数量的线程。当用于收集的并发线程不能足够快地恢复内存时,它将被触发。

线程的数量可以由-XX:ParallelGCThreads选项控制。

JEP 316:替代内存设备上的堆分配

此更改的目标是使HotSpot VM能够在用户指定的备用内存设备(如NV-DIMM)上分配Java对象堆。

要在这样的内存中分配堆,我们可以添加一个新选项,-XX:AllocateHeapAt=<path>。此选项将获取文件系统的路径,并使用内存映射来实现在内存设备上分配对象堆的所需结果。现有的堆相关标志(如-Xmx-Xms等)和垃圾收集相关标志将继续像以前一样工作。

JEP 296:将JDK Forest整合到单个存储库中

作为此更改的一部分,JDK Forest的许多存储库被合并到一个存储库中,以简化和简化开发。

在jdk9中有八个repos:rootcorbahotspotjaxpjaxwsJDKlangtoolsnashorn。在合并Forest中,Java模块的代码通常组合在一个顶级src目录下。例如,今天在JDK Forest中有基于模块的目录,如:

$ROOT/jdk/src/java.base
...
$ROOT/langtools/src/java.compiler
...

consolidated forest中,此代码被组织为:

$ROOT/src/java.base
$ROOT/src/java.compiler
...

JEP 310:应用类数据共享

此功能的目标是改进启动占用空间,扩展现有的类数据共享(“CDS”)功能,以允许将应用程序类放置在共享存档中。

jdk5中引入的类数据共享允许将一组类预处理到一个共享的归档文件中,然后在运行时映射内存以减少启动时间。当多个jvm共享同一个归档文件时,它还可以减少动态内存占用。

目前,CDS只允许引导类加载器加载已存档的类。应用程序cd允许内置系统类装入器、内置平台类装入器和自定义类装入器装入存档的类。

指定-XX:+UseAppCDS命令行选项以启用系统类加载器、平台类加载器和其他用户定义类加载器的类数据共享。

JEP 314:额外的Unicode语言标记扩展

它的目标是提高java.util.Locale语言环境以及相关的API来实现BCP 47语言标记的额外Unicode扩展。对BCP47语言标记的支持最初是在JavaSE7中添加的,对Unicode语言环境扩展的支持仅限于日历和数字。这个JEP将在相关JDK类中实现最新LDML规范中指定的更多扩展。

此JEP将添加对以下附加扩展的支持:

  • cu(货币类型)
  • fw(每周第一天)
  • rg(区域覆盖)
  • tz(时区)

修改的相关API有:

java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider

JEP 319::根证书

cacerts密钥库是JDK的一部分,它包含一组根证书,可用于在各种安全协议中使用的证书链中建立信任。但是,JDK源代码中的cacerts密钥库当前为空。

cacerts密钥库将由Oracle的java se根CA程序的CAs颁发的一组根证书填充。许多供应商已经签署了所需的协议,并为每个供应商提供了一个根证书列表。那些没有签署协议的人将不包括在内。那些需要更长时间处理的将包含在下一个版本中。

这也意味着Oracle和openjdk二进制文件在功能上是相同的。关键的安全组件(如TLS)将在OpenJDK构建中默认工作。

JEP 317:实验性的基于Java的JIT编译器

这个特性使基于Java的JIT编译器Graal能够在Linux/x64平台上作为一个实验性的JIT编译器使用。Graal将使用jdk9中引入的JVM编译器接口(JVMCI)。Graal已经在JDK中,所以将它作为一个实验性的JIT来启用主要是一个测试和调试工作。

要启用Graal作为JIT编译器,请在java命令行上使用以下选项:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

Graal是用Java从头开始的对JIT编译器的完全重写。以前的JIT编译器是用C++编写的。

JEP 312:线程本地握手

这个JEP为改进VM性能打下了基础,它使得在不执行全局VM safepoint的情况下对应用程序线程执行回调成为可能。这意味着JVM可以停止单个线程,而不仅仅是所有线程。

线程本地握手最初将在x64和SPARC上实现。其他平台将回落至正常安全点。新产品选项-XX:ThreadLocalHandshakes(默认值true)允许用户在支持的平台上选择正常的安全点。

JEP 313:删除Native-Header生成工具

它将从JDK中删除javah工具,JDK是编译JNI代码时生成头文件的单独工具,因为这可以通过javac完成。

这是Java10的另一个特性,主要关注内务管理。

新添加的API和选项

Java10中增加了73个新的API。我们来看看其中几个有代表性的:

API 描述
Optional.orElseThrow() 向可选类添加了一个新方法orelsethornw。它是现有get方法的同义词,现在是现有get方法的首选替代方法。
List.copyOf, Set.copyOf, Map.copyOf 这些方法从现有实例创建新的集合实例。
Collectors.toUnmodifiableList,

Collectors.toUnmodifiableSet,

Collectors.toUnmodifiableMap

这些方法允许将流的元素收集到不可修改的集合中
--jdk.disableLastUsageTracking 为正在运行的VM禁用JRE上次使用情况跟踪。
--add-stylesheet 为在生成的文档中使用多个样式表提供支持。
--main-stylesheet 帮助区分主样式表和任何其他样式表。
@summary Tag  添加以显式指定用作API描述摘要的文本。默认情况下,API描述的摘要是从第一句话推断出来的。

删除的API和选项

API 描述
LookAndFeels
Runtime.getLocalizedInputStream,

Runtime.getLocalizedOutputStream

是过时的国际化机制的一部分,没有已知的用途。
RMI Server-Side Multiplex Protocol Support 它在jdk9中被禁用,现在已被删除。
Common DOM APIs 这个com.sun.java.browser.plugin2DOM,还有sun.plugin.dom.DOMObject API已被删除。应用程序可以使用netscape.javascript.JSObject操作DOM。
FlatProfiler 在jdk9中已被弃用,通过删除实现代码已被废弃。
-Xoss, –Xsqnopause, -Xoptimize, -Xboundthreads, -Xusealtsigs 选项已删除。
policytool policytool安全工具已从JDK中删除。
Deprecated Classes in com.sun.security.auth.** 下面的类现在被删除:

  • 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

总的来说,java10有许多我们在日常编程中可能不使用的特性,但它仍然有许多在幕后工作的特性,使它成为一个重要的里程碑。