Java 17是标准Java的一个新的长期支持(LTS)版本,现在可以用于生产使用。甲骨文还宣布,LTS版本将每两年发布一次,而不是过去的三年一次。LTS版本将获得至少八年的产品支持。非lts版本将获得Oracle 6个月的支持。
标准Java新版本的新功能包括支持特定于上下文的反序列化过滤器(这是一种安全性增强),以及预览switch语句的模式匹配。JDK 17提供了自上次LTS发布以来添加的所有功能,JDK 11它是三年前推出的。
甲骨文Java平台组副总裁Georges Saab说,更频繁的LTS发布将为那些只想使用LTS版本的公司提供更快的访问新功能的机会。下一个LTS版本将于2023年发布Java 21。对于JDK 17, Oracle将允许在生产环境中免费使用Oracle JDK二进制文件三年,比下一个LTS晚一年。但这并不包括企业生产支持订阅。
来自应用程序监控提供商New Relic客户群的数据(代表了数千万个生产jvm)显示,LTS发布几乎得到了一致的部署。New Relic发现,几乎100%的用户都在运行JDK 11或JDK 8,这是两个最新的LTS版本。New Relic表示,90%的人使用JDK 11, 10%的人使用JDK 8。
不过,甲骨文表示,这六个月版本的下载量一直在稳步增长。开发人员喜欢尝试六个月的版本,而企业则希望部署LTS版本。
JDK 17的生产版本可以在oracle.com.OpenJDK开源构建也有。JDK 17的新特性包括:
- 特定于上下文的反序列化过滤器允许应用程序通过jvm范围的过滤器工厂来配置特定于上下文的动态选择的反序列化过滤器,该过滤器被调用来为每个序列化操作选择一个过滤器。在解释这个提议背后的动机时,Oracle说反序列化不可信的数据本质上是一种危险的活动,因为传入数据流的内容决定了所创建的对象、它们的字段值以及它们之间的引用。在许多使用中,流中的字节是从未知的、不受信任的或未经身份验证的客户端接收的。通过仔细构造流,攻击者可以恶意地执行任意类中的代码。如果对象构造具有改变状态或调用其他操作的副作用,那么这些操作可能会损害应用程序对象、库对象和Java运行时的完整性。禁用序列化攻击的关键是防止任意类的实例被反序列化,从而防止直接或间接执行它们的方法。中引入了反序列化过滤器Java 9使应用程序和库代码在反序列化传入数据流之前验证传入数据流。这段代码提供了验证逻辑
java.io.ObjectInputFilter
当它创建反序列化流时。然而,依赖流的创建者显式地请求验证是有局限性的。JDK增强建议290通过引入jvm范围内的反序列化过滤器(可以通过API、系统属性或安全属性进行设置)来解决这些限制,但是这种方法也有局限性,特别是在复杂的应用程序中。一个更好的方法是配置每个流过滤器,这样它们就不需要每个流创建者的参与。计划中的增强应该帮助开发人员为每个反序列化上下文和用例构建和应用适当的过滤器。 - 与恢复始终严格的浮点语义,浮点运算将始终严格,而不是同时具有严格的浮点语义(
strictfp
)和略有不同的默认浮点语义。这将恢复语言和VM的原始浮点语义,匹配Java标准版1.2中引入严格浮点模式和默认浮点模式之前的语义。这项工作的目标包括简化数字敏感库的开发,包括java.lang.Math
而且java.lang.StrictMath
.20世纪90年代后期改变默认浮点语义的动力来自于原始Java语言和JVM语义之间的糟糕交互,以及流行x86架构的x87浮点协处理器指令集的一些特性。在所有情况下匹配精确的浮点语义,包括次标准操作数和结果,需要大量额外的指令开销。在没有溢出或下溢的情况下匹配结果可以用更少的开销完成,这基本上是Java SE 1.2中引入的经过修订的默认浮点语义所允许的。但是SSE2(流式SIMD扩展2)扩展,大约从2001年开始在奔腾4和更高的处理器中提供,可以以直接的方式支持严格的JVM浮点操作,没有不必要的开销。由于Intel和AMD支持SSE2和以后的扩展,这些扩展允许对严格浮点语义的自然支持,因此使用不同于严格浮点语义的默认浮点语义的技术动机已不复存在。 - 弃用安全管理器,准备在未来的版本中删除。追溯到Java 1.0, Security Manager一直是保护客户端Java代码的主要手段,很少用于保护服务器端代码。该提案的一个目标是评估是否需要新的api或机制来解决已经使用Security Manager的特定狭窄用例,例如阻塞
退出系统::
.计划要求弃用安全管理器,以便与遗留的Applet API一起删除,后者也将在JDK 17中被弃用。 - 预览模式匹配
开关
扩展Java中的模式语言以允许开关
表达式和语句将针对许多模式进行测试,每个模式都具有特定的操作。这使得复杂的面向数据的查询能够简洁而安全地表达。该特性的目标包括扩展的表达性和应用开关
的历史零敌对状态,从而使模式能够出现在case标签中开关
当需要时,并引入两种模式:保护模式
,允许使用任意布尔表达式来细化模式匹配逻辑,以及带括号的模式
,可以解决一些解析歧义。在JDK 16,运算符
运算符被扩展为获取类型模式并执行模式匹配。建议的适度扩展允许简化熟悉的实例-强制转换习惯用法。 - JDK内部的强封装,除了关键的内部api,例如
sun.misc.Unsafe
,将不再可能像JDK 9到JDK 16中那样,通过单个命令行选项放松内部元素的强封装。该计划的目标包括提高JDK的安全性和可维护性,并鼓励开发人员从内部元素迁移到标准api。 - 移除远程方法调用(RMI)激活机制同时保留RMI的其余部分。RMI激活机制已经过时和废弃,已弃用JDK 15.
- 的外部函数和内存API它允许Java程序与Java运行时之外的代码和数据进行互操作。通过高效地调用外部函数(即JVM外部的代码)和安全地访问外部内存(即不受JVM管理的内存),API使Java程序能够调用本机库和处理本机数据,而没有JNI (Java本机接口)的脆弱性和风险。提出的API是两个API的进化——外部内存访问API和外部链接器API。外部内存访问API在2019年针对Java 14作为孵化API,并在Java 15和Java 16中重新孵化。外部链接器API的目标是在2020年底将Java 16作为孵化API。API计划的目标包括易用性、性能、通用性和安全性。
- 集成到JDK 16作为一个孵化API,平台不可知论者向量的API将在JDK 17中再次孵化,提供一种机制来表达矢量计算,在运行时可靠地编译为支持的CPU架构上的最佳矢量指令。这实现了比等效标量计算更好的性能。在JDK 17中,vector API在性能和实现方面得到了增强,包括将字节向量转换为布尔数组和从布尔数组转换字节向量的增强。
- 密封的类和接口限制哪些其他类或接口可以扩展或实现它们。该提案的目标包括允许类或接口的作者控制负责实现它的代码,提供一种比访问修饰符更具声明性的方式来限制超类的使用,并通过为模式的详尽分析提供基础来支持模式匹配的未来方向。这个功能可以帮助API设计人员构建更具弹性的代码。
- 移除实验性的AOT和JIT编译器该系统很少使用,但需要大量的维护工作。该计划要求维护java级JVM编译器接口,以便开发人员可以继续使用编译器的外部构建版本进行JIT编译。AOT编译(jaotc工具)被纳入JDK 9作为一个实验特征。该工具使用Graal编译器,它本身是用Java编写的,用于AOT编译。这些实验特征没有包括在JDK 16没有人抱怨。根据规定的计划,三个JDK模块将被移除:Aot (jaotc工具);internal.vm.compiler, Graal编译器;和jdk.internal.vm.compiler.management, Graal MBean。与AOT编译相关的热点代码也将被删除。
- 将JDK移植到MacOS/AArch64作为对苹果计划将其Macintosh电脑从x64过渡到AArch64.针对Java的AArch64移植已经存在于Linux中,针对Windows的工作正在进行中。Java构建器希望通过使用条件编译从这些端口重用现有的AArch64代码,这是JDK端口的标准,以适应低级约定的差异,如应用程序二进制接口和保留的处理器寄存器集。MacOS/AArch64的更改可能会破坏现有的Linux/AArch64、Windows/AArch64和MacOS/x64端口,但通过集成前测试将降低风险。
- 弃用Applet API以删除.这个API本质上是无关紧要的,因为所有web浏览器供应商要么已经删除了对Java浏览器插件的支持,要么已经宣布了这样做的计划。Applet API以前已弃用,但不用于删除Java 92017年9月。
- 一个新的MacOS渲染管道,使用Apple Metal API作为现有管道的替代方案,使用已弃用的OpenGL API。该提议旨在为使用MacOS Metal框架的Java 2D API提供一个功能齐全的渲染管道,并为苹果从未来版本的MacOS中删除OpenGL API做好准备。该管道旨在与现有的OpenGL管道具有相同的功能,在选定的应用程序和基准测试中具有相同或更好的性能。将创建适合当前Java 2D模型的干净架构。该管道将与OpenGL管道共存,直到被淘汰。该提案的目标不是添加任何新的Java或JDK api。
- 增强的伪随机数生成器这将为伪随机数生成器(PRNG)提供新的接口类型和实现,包括可跳式PRNG和额外的一类可分割PRNG算法(LXM)。一个新的界面,
RandomGenerator
,将为所有现有和新的prng提供统一的API。将提供四个专门的RandomGenerator接口。该计划的动机是关注Java中伪随机数生成方面的多个改进领域。这项工作不需要提供大量其他PRNG算法的实现。但是添加了三种常见的算法,它们已经广泛地部署在其他编程语言环境中。该计划的目标包括:- 更容易在应用程序中互换使用各种PRNG算法。
- 改进了对基于流的编程的支持,提供PRNG对象的流。
- 消除现有PRNG类中的代码重复。
- 保留类的现有行为
java.util.Random
.