Java 10 新特性概述

  Java 10是其23年历史中最快发布的java版本。Java因其缓慢的增长和发展而受到批评,但Java 10刚刚破坏了这个概念。Java 10是一个具有许多未来变化的版本,其范围和影响可能并不明显,但却很深远。

  在本文中,我们将讨论Java10发行版中添加的各种功能。在此之前,让我们回顾一下java发布模型中引入的一些变化。

长期支持模型

  从2017年开始,甲骨文和Java社区宣布将向Java推出全新的6个月版本更新的节奏,将Oracle Java SE产品转向了长期支持(LTS)模型。

  LTS版本的产品将提供Oracle的主要和持续支持,并将每3年定位一次。

  每个Java版本都是在一个或两个主要功能确定之后开始建模的,这些功能推动了版本发布。任何障碍都会推迟发布和推迟上市。Project Jigsaw是Java 9的一个主要特性,它将发布日期延期数次,发布时间推迟了超过1.5年。6个月的发布节奏将遵循总发布计划。总发布计划每6个月会有一个时间表,使已完成的特征登上此次发布计划; 否则他们会等下一批发布计划。

Oracle JDK vs Open JDK

  为了更加开发人员友好,Oracle和Java社区现在将OpenJDK二进制文件作为主要JDK推进。对比起以前,这是一个很大的进步,因为JDK二进制文件是由Oracle授权,Oracle在再次分发的方面有各种限制。(律师函警告)然而,Oracle将继续生产他们的JDK,但仅限于长期支持版本。这是一个向更多云和容器友好的举措,因为OpenJDK二进制文件可以作为容器的一部分进行分发。

  Open JDK二进制文件将每6个月发布一次,而Oracle JDK二进制文件将每3年发布一次(LTS版本)。

  大型组织需要时间在版本之间移动,他们会坚持使用该版本,直到他们必须升级。Java 6的行业采用率超过了Java 7,然后行业逐渐转向Java 8。在我看来,LTS版本将是企业最青睐的版本。但是,它是否是LTS版本的Oracle JDK或Open JDK尚未公布,部分原因是因为有多种云空间。

Java 9和10是非LTS版本。将于2018年9月发布的Java 11将是LTS版本。

Java 10新特性

这里写图片描述
  让我们来看看Java 10中新特性前瞻。

基于时间的版本发布(JEP 322)

  通过采用基于时间的发布周期,Oracle针对当前和未来基于时间的发布模型更改了Java SE平台和JDK的版本字符串模式以及相关的版本控制信息。

  版本号的新模式是:

$FEATURE.$INTERIM.$UPDATE.$PATCH
  • $ FEATURE:计数器将每6个月递增一次,并将基于功能发布版本,例如:JDK 10,JDK 11。
  • $ INTERIM:对于包含兼容的错误修复和增强,而没有不兼容的更改的非功能版本,计数器将递增。通常这将是零,因为六个月内不会有临时释放。这保留了将来版本的发布模型。
  • $ UPDATE:计数器将针对兼容的更新版本递增,以修复新功能中的安全问题,回归和错误。这在功能发布后一个月更新,之后每3个月更新一次。2018年4月发行版为JDK 10.0.1,7月发行版为JDK 10.0.2,依此类推
  • $ PATCH:计数器将增加紧急版本以解决关键问题。

      添加了新的API以编程方式获取这些计数器值。让我们来看看:

Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();

  现在,让我们看看Java启动器,它返回版本信息:

$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

  版本号格式为”10”,因为没有其他计数器不是零。发布日期已添加,18.3可以读作2018年和第3个月,构建10 + 46是版本10的第46个版本。

局部变量类型推断(JEP 286)

  本地变量类型推断是Java 10中面向开发人员的最大新功能。它使用初始值设定项向局部变量的声明添加类型推断。本地类型推断只能在以下场景中使用:

  • 仅限于具有初始化程序的局部变量
  • 增强的for循环的索引
  • for循环中声名的局部变量

我们来看看它的用法:

var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList<String>
// Index of Enhanced For Loop
for (var number : numbers) {
    System.out.println(number);
}
// Local variable declared in a loop
for (var i = 0; i < numbers.size(); i++) {
    System.out.println(numbers.get(i));
}

  您可以在我们关于java 10局部变量类型推断的文章中阅读更多相关信息。

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

  此功能使基于Java的JIT编译器Graal可用作Linux / x64平台上的实验性JIT编译器。这是迄今为止Java 10功能列表中最具未来感的内容。

  Graal是在Java 9中引入的。它是我们习惯使用的JIT编译器的替代品。它是JVM的插件,这意味着JIT编译器不依赖于JVM,它可以动态插入并替换为JVMCI兼容的任何其他插件(Java级JVM编译器接口)。它还带来了Java世界中的Ahead of Time(AOT)编译。它还支持多语言语言解释。

  “用Java编写的基于Java的即时编译器将java字节码转换为机器代码。”这令人困惑吗?如果JVM是用Java编写的,那么你不需要JVM来运行JVM吗?JVM可以编译为AOT,然后JIT编译器可以在JVM中使用,以通过实时代码优化来提高性能。

  Graal是从头开始用Java完全重写JIT编译器。以前的JIT编译器是用c ++编写的。它被认为是任何编程语言进化的最后阶段之一。

  您可以使用以下jvm参数切换到Graal:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

  您可以从Chris Seaton presentation中了解更多关于Graal的信息。

应用类数据(Class-Data)共享(JEP 310)

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

  JVM在启动时执行一些初步步骤,其中一个步骤是在内存中加载类。如果有几个具有多个类的jar,则第一个请求中的滞后清晰可见。因启动时间至关重要,这成为无服务器架构的一个问题。为了缩短应用程序启动时间,可以使用Application类数据共享。这个想法是通过在不同的Java进程之间共享公共类元数据来减少占用空间。这可以通过以下3个步骤来实现:

确定要归档的类:使用java启动程序创建要归档的文件列表,这可以通过设置以下参数来实现:

$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld

创建AppCDS存档:使用java启动程序创建要用于Application CDS的文件列表的存档,这可以通过设置以下参数来实现:

$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar

使用AppCDS存档:使用带有以下参数的Java启动程序来使用Application CDS。

$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld

G1垃圾收集器的并行 Full GC(JEP 307)

  G1 垃圾收集器在JDK 9中为默认垃圾收集器。G1避免任何Full GC,但是当垃圾收集的并发线程无法快速恢复内存时,用户体验受到影响。

  此更改通过使Full GC并行来改善G1最坏情况发生率。此次更改的一部分为将G1收集器中的mark-sweep-compact算法并行化,并且当收集的并发线程无法足够快地恢复内存时将触发该算法。

垃圾收集器接口(JEP 304)

  这个JEP是未来的变革。它通过引入通用的垃圾收集器接口改进了不同垃圾收集器的代码隔离。

  此更改为内部GC代码提供了更好的模块化。它将有助于在不更改现有代码库的情况下添加新GC,也有助于删除或管理以前的GC。

其他Unicode语言标记扩展(JEP 314)

  此功能增强了java.util.Locale和其相关API,以实现BCP 47语言标记的其他Unicode扩展。从Java SE 9开始,支持的BCP 47 U语言标记扩展名为canu。此JEP将添加对以下附加扩展的支持:

  • cu(货币类型 currency type)
  • fw(一周的第一天 first day of week)
  • rg(区域覆盖 region override)
  • tz(时区 time zone)

      为了支持这些附加扩展,对各种API进行了更改,以便根据U或其他扩展提供信息。

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)

  为了促进openjdk的发展并使其对社区用户更具吸引力,此功能在JDK中提供了一组默认的根证书颁发机构(CA)证书。这也意味着Oracle JDK和Open JDK二进制文件在功能上都是相同的。

  默认情况下,TLS等关键安全组件将在OpenJDK构建中运行。

线程局部握手(JEP 312)

  这是一个内部JVM功能,可以提高性能。

  握手操作是在该线程处于安全点的安全状态时,为每个JavaThread执行的回调。回调由线程自身或VM线程执行,同时保持线程处于阻塞状态。

  此功能提供了一种在线程上执行回调而无需执行全局VM安全点的方法。让低开销地停止单个线程成为一种可能,而不仅仅是停止所有线程或没有线程。

替代存储设备上的堆分配(JEP 316)

  应用程序已经变得非常耗费内存,因云原生(cloud native)应用程序,内存数据库(memory databases),流应用(streaming )程序的数量的增加。为了满足这些服务,可以使用各种存储器架构。此功能增强了HotSpot VM在另一个内存设备(例如用户指定的NV-DIMM)上分配Java对象堆的功能。

  此JEP的目标是具有与DRAM相同语义的备用存储器设备,包括原子操作的语义,因此可以在不对现有应用程序代码进行任何更改的情况下将其用于代替对象堆的DRAM。

删除Native-Header生成工具 - javah(JEP 313)

  这是一个内务更改,内容为从JDK中删除javah工具。功能性工具javac作为JDK 8的一部分添加,它提供了在编译时编写native 头文件的能力,使其javah无用。

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

  多年来,JDK代码库中有各种Mercurial存储库。不同的存储库确实提供了一些优势,但它也有各种操作缺点。作为此更改的一部分,将JDK forest 的大量存储库合并到一个存储库中,以简化配置和开发。

API更改

Java 10添加并删除了(不是废弃)API。

Java 9引入了增强的弃用功能,其中某些API标记为在将来的版本中删除。

API已删除:您可以在此处找到已删除的API 。

API已添加:Java 10中添加了73个新API。您可以在此处找到添加的API以及比较。

我们来看几个补充:

  • 使用静态copyOf(Collection)方法添加List,Map和Set Interfaces。它返回一个包含所提供条目的不可修改的List,Map或Set。对于List,如果随后修改了给定的List,则返回的List将不会反映这些修改。
  • Optional 及其原始变体获取方法orElseThrow()。这与get()完全相同,但java doc声明它是get()的首选替代方法
  • Collectors类获取各种收集不可修改集合的方法(Set,List,Map)
List<String> actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// New API added - Creates an UnModifiable List from a List.
List<String> copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("Robert De Niro"); Will generate an
// UnsupportedOperationException
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]

String str = "";
Optional<String> name = Optional.ofNullable(str);
// New API added - is preferred option then get() method
name.orElseThrow(); // same as name.get()  

// New API added - Collectors.toUnmodifiableList
List<String> collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("Tom Hanks"); // Will generate an
// UnsupportedOperationException

原文地址:Java 10 Features written by Rakesh Kumar
完整代码:Github

猜你喜欢

转载自blog.csdn.net/why_still_confused/article/details/82256924