Java 10新特性
Java 10是其23年历史中最快的java版本。Java因其缓慢的增长和发展而受到批评,但Java 10刚刚破坏了这一概念。Java 10是一个具有许多未来变化的版本,其范围和影响可能不明显但是很有用。
在本文中,我们将讨论Java10发行版中添加的各种功能。在此之前,让我们回顾一下java发布模型中引入的一些变化。
目录[ 隐藏 ]
长期支持模型
从2017年开始,Oracle和Java社区宣布将向Java推出新的6个月节奏。它转向了Oracle Java SE产品的长期支持(LTS)模型。
这是什么意思?
LTS版本的产品将提供Oracle的一流和持续支持,并将每三年定位一次。
每个Java版本都是在一个或两个主要功能之后建模的,这些功能推动了发布。任何障碍,推迟发布和推迟上市。Project Jigsaw是Java 9的一个主要特性,它将发布日期推迟了几次,发布时间推迟了超过1。5年。6个月的节奏发布将遵循发布列车。发布列车每6个月会有一个时间表。使切割的特征登上火车; 否则他们会等下一班火车。
Oracle JDK vs Open JDK
为了更加开发人员友好,Oracle和Java社区现在将OpenJDK二进制文件作为主要JDK推进。从早期开始,JDK二进制文件是正确的并且由Oracle授权,这对于重新分配有各种限制,这是一个很大的缓解。然而,Oracle将继续生产他们的JDK,但仅限于长期支持版本。这是一个向更多云和容器友好的方向,因为开放的JDK二进制文件可以作为容器的一部分进行分发。
这是什么意思?
Open JDK二进制文件将每6个月发布一次,而Oracle JDK二进制文件将每3年发布一次(LTS版本)。
将采用哪些JDK二进制文件?
大型组织需要时间在版本之间移动; 他们坚持到版本,直到他们可以。Java 6的行业采用超过Java 7,然后Industry逐渐转向Java 8。在我看来,LTS版本将是企业最青睐的版本。但是,它是否是LTS版本的Oracle JDK或Open JDK尚未公布,部分原因是因为云空间有很多。
Java 9和10是非LTS版本。将于2018年9月发布的Java 11将是LTS版本。
Java 10功能
让我们来看看Java 10中提供的功能。
通过采用基于时间的发布周期,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个版本。对于JDK 10.0.1的假设构建93,构建将是10.0.1 + 93
本地变量类型推断是Java 10中面向开发人员的最大新功能。它使用初始值设定项添加了对局部变量声明的类型推断。本地类型推断只能在以下场景中使用:
我们来看看它的用法:
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编译器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演讲中了解有关Graal的更多信息。
此功能有助于改善启动占用空间,扩展现有的类数据共享(“CDS”)功能,以允许将应用程序类放在共享存档中。
JVM在启动时执行一些预备步骤,其中一个步骤是在内存中加载类。如果有几个具有多个类的罐子,则第一个请求中的滞后清晰可见。这成为无服务器架构的问题,其中启动时间至关重要。为了缩短应用程序启动时间,可以使用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 垃圾收集器在JDK 9中默认设置.G1垃圾收集器避免了任何完整的垃圾收集,但是当收集的并发线程无法快速恢复内存时,用户体验受到影响。
此更改通过使完整GC并行来改善G1最坏情况延迟。G1收集器中的mark-sweep-compact算法并行化,作为此更改的一部分,并且当并发收集的线程无法足够快地恢复内存时将触发该算法。
这个JEP是未来主义的变革。它通过引入常见的垃圾收集器接口改进了不同垃圾收集器的代码隔离。
此更改为内部GC代码提供了更好的模块化。将来有助于在不更改现有代码库的情况下添加新GC,还有助于删除或管理以前的GC。
此功能增强了java.util.Locale和相关API,以实现BCP 47语言标记的其他Unicode扩展。从Java SE 9开始,支持的BCP 47 U语言标记扩展名为 - ca和nu。此JEP将添加对以下附加扩展的支持:
为了支持这些附加扩展,对各种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
为了促进OpenJDK并使其对社区用户更具吸引力,此功能在JDK中提供了一组默认的根证书颁发机构(CA)证书。这也意味着Oracle和Open JDK二进制文件在功能上都是相同的。
诸如TLS之类的关键安全组件将在未来的OpenJDK构建中默认工作。
这是一个内部JVM功能,可以提高性能。
握手操作是在该线程处于安全点安全状态时为每个JavaThread执行的回调。回调由线程本身或VM线程执行,同时保持线程处于阻塞状态。
此功能提供了一种在线程上执行回调而无需执行全局VM安全点的方法。让它既可能又便宜地停止单个线程,而不仅仅是所有线程或没有线程。
应用程序已经变得非常耗费内存,云原生应用程序,内存数据库,流应用程序也在增加。为了迎合这些服务,可以使用各种存储器架构。此功能增强了HotSpot VM在另一个内存设备(例如用户指定的NV-DIMM)上分配Java对象堆的功能。
此JEP的目标是具有与DRAM相同语义的备用存储器设备,包括原子操作的语义,因此可以在不对现有应用程序代码进行任何更改的情况下,为对象堆使用DRAM代替DRAM。
这是从JDK中删除javah工具的内务更改。工具功能javac
作为JDK 8的一部分添加,它提供了在编译时编写本机头文件的能力,使其javah
无用。
多年来,JDK代码库中已经有各种Mercurial存储库。不同的存储库确实提供了一些优势,但它也有各种操作缺点。作为此更改的一部分,JDK林的大量存储库将合并到一个存储库中,以简化和简化开发。
Java 10添加并删除了(Yes It不是Typo)API。
Java 9引入了增强的弃用,其中某些API标记为在将来的版本中被删除。
API已删除:您可以在此处找到已删除的API 。
API已添加:Java 10中添加了73个新API。您可以在此处找到添加的API以及比较。
我们来看几个补充:
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
-
基于时间的发布版本控制(JEP 322)
-
局部变量类型推断(JEP 286)
-
仅限于具有初始化程序的本地变量
-
增强的for循环或索引的索引
-
本地声明为for循环
-
-
实验性基于Java的JIT编译器(JEP 317)
-
应用类 - 数据共享(JEP 310)
-
用于G1的并行全GC(JEP 307)
-
垃圾收集器接口(JEP 304)
-
其他Unicode语言标记扩展(JEP 314)
-
铜(货币类型)
-
fw(一周的第一天)
-
rg(区域覆盖)
-
tz(时区)
-
-
根证书(JEP 319)
-
线程局部握手(JEP 312)
-
替代存储设备上的堆分配(JEP 316)
-
删除Native-Header生成工具 - javah(JEP 313)
-
将JDK Forest整合到单个存储库中(JEP 296)
-
API更改
- 使用静态copyOf(Collection)方法添加List,Map和Set Interfaces。它返回一个包含所提供条目的不可修改的List,Map或Set。对于List,如果随后修改了给定的List,则返回的List将不会反映这些修改。
- 可选及其原始变体获取方法orElseThrow()。这与get()完全相同,但java doc声明它是get()的首选替代方法
- Collectors类获取各种收集不可修改集合的方法(Set,List,Map)
结论
在本文中,我们介绍了Java 10的不同新功能。如果您认为这里遗漏了重要内容,请通过评论告诉我们。
像往常一样,您可以在这里查看GitHub上的完整代码。