快来看看 Java17的新特性

「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

Java 17是标准Java的一个新的长期支持(LTS)版本,现在已经可以用于生产。甲骨文公司还宣布,LTS版本(获得至少八年的产品支持)今后将每两年发布一次,而过去是每三年发布一次。非LTS版本从甲骨文获得6个月的支持。

在新版标准Java的新功能中,包括支持上下文特定的反序列化过滤器,这是一项安全改进,以及预览开关语句的模式匹配。JDK 17具有自三年前发布的最后一个LTS版本(JDK 11)以来所增加的所有功能。

甲骨文公司Java平台集团副总裁Georges Saab说,更频繁的LTS版本将为那些只想使用LTS版本的公司提供更快的新功能访问。下一个LTS版本将是2023年的Java 21。有了JDK 17,甲骨文将允许在生产中免费使用甲骨文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范围内的过滤器工厂为每个序列化操作选择过滤器来配置上下文特定和动态选择的反序列化过滤器。在解释这项提议背后的动机时,甲骨文公司说,反序列化不受信任的数据是一种固有的危险活动,因为传入数据流的内容决定了创建的对象、其字段的值以及它们之间的引用。在许多情况下,数据流中的字节是从一个未知的、不受信任的或未经认证的客户端接收的。通过对流的仔细构建,对手可以使任意类中的代码以恶意的方式执行。如果对象的构建有改变状态或调用其他动作的副作用,这些动作可能会损害应用程序对象、库对象和Java运行时的完整性。禁用序列化攻击的关键是防止任意类的实例被反序列化,从而防止直接或间接执行其方法。在Java 9中引入了反序列化过滤器,使应用程序和库代码在反序列化之前验证传入的数据流。这段代码在创建反序列化流时作为java.io.ObjectInputFilter提供验证逻辑。然而,依靠流的创建者明确请求验证有其局限性。JDK增强提案290通过引入一个JVM范围内的反序列化过滤器来解决这些限制,该过滤器可以通过API、系统属性或安全属性来设置,但这种方法也有局限性,特别是在复杂的应用程序中。一个更好的方法是配置每个流的过滤器,使其不需要每个流创建者的参与。计划中的增强功能应该帮助开发者为每个反序列化环境和用例构建和应用适当的过滤器。
  • 随着始终严格的浮点语义的恢复,浮点操作将变得一致严格,而不是同时拥有严格的浮点语义(strictfp)和微妙不同的默认浮点语义。这将恢复语言和虚拟机的原始浮点语义,与Java标准版1.2中引入严格和默认浮点模式之前的语义相匹配。这项工作的目标包括简化数字敏感库的开发,包括java.lang.Math和java.lang.StrictMath。1990年代末,改变默认浮点语义的动力源于原始Java语言和JVM语义与流行的x86架构的x87浮点协处理器指令集的一些特殊性之间的不良互动。在所有情况下匹配准确的浮点语义,包括非正常操作数和结果,需要大量额外指令的开销。在没有溢出或下溢的情况下,匹配结果可以用较少的开销完成,这也是Java SE 1.2中引入的修订后的默认浮点语义所允许的。但是,从2001年左右开始在奔腾4及以后的处理器中搭载的SSE2(Streaming SIMD Extensions 2)扩展,可以直接支持严格的JVM浮点操作,而不会产生过多的开销。由于英特尔和AMD支持SSE2和后来的扩展,允许自然地支持严格的浮点语义,因此,有一个不同于严格的默认浮点语义的技术动机不再存在。
  • 废弃了安全管理器,准备在未来的版本中删除。追溯到Java 1.0,安全管理器一直是保护客户端Java代码安全的主要手段,很少被用于保护服务器端代码。该提案的一个目标是评估是否需要新的API或机制来解决安全管理器所使用的特定的狭隘用例,如阻止System::exit。计划要求废弃安全管理器,以便与传统的Applet API一起删除,后者也将在JDK 17中被废弃。
  • switch的模式匹配预览扩展了Java中的模式语言,使switch表达式和语句可以针对一些模式进行测试,每个模式都有一个特定的动作。这使得复杂的面向数据的查询能够被简明而安全地表达。这个功能的目标包括:通过使模式出现在案例标签中,扩大switch表达式和语句的表现力和应用,在需要时放宽switch的历史无效性,并引入两种模式:有防护的模式,它允许用任意的布尔表达式来完善模式匹配逻辑;以及圆括号模式,它解决了一些解析上的模糊问题。在JDK 16中,instanceof操作符被扩展为接受一个类型模式并执行模式匹配。所提出的适度扩展允许简化熟悉的instanceof-and-cast成语。
  • 除了 sun.misc.Unsafe 等关键的内部 API 之外,对 JDK 内部元素的强封装将使人们不再可能通过一个命令行选项来放松对内部元素的强封装,这在 JDK 9 到 JDK 16 中是可以做到的。该计划的目标包括提高JDK的安全性和可维护性,鼓励开发者从内部元素迁移到标准API。
  • 删除了远程方法调用(RMI)激活机制,同时保留了 RMI 的其余部分。RMI 激活机制已经过时并被废弃,在 JDK 15 中被废弃删除。
  • 国外函数和内存API是在孵化阶段引入的,它允许Java程序与Java运行时之外的代码和数据进行互操作。通过有效地调用外来函数,即JVM之外的代码,以及安全地访问外来内存,即不由JVM管理的内存,该API使Java程序能够调用本地库并处理本地数据,而没有JNI(Java Native Interface)的脆性和风险。提出的API是由两个API演变而来--国外内存访问API和国外链接器API。外国内存访问API在2019年作为一个孵化API针对Java 14,并在Java 15和Java 16中重新孵化。外国链接器API的目标是在2020年底作为孵化API应用于Java 16。该API计划的目标包括易用性、性能、通用性和安全性。
  • 作为孵化API集成到JDK 16中,平台无关的矢量API将在JDK 17中再次孵化,提供一种机制来表达矢量计算,在运行时可靠地编译为支持的CPU架构上的最佳矢量指令。这比同等的标量计算实现了更好的性能。在JDK 17中,向量API在性能和实现方面得到了增强,包括增强了将字节向量转换为布尔数组和从布尔数组中转换的能力。
  • 封闭类和接口限制了哪些其他类或接口可以扩展或实现它们。该提案的目标包括允许类或接口的作者控制哪些代码负责实现它,提供一种比访问修饰符更明确的方式来限制超类的使用,并通过为模式的详尽分析提供基础来支持模式匹配的未来方向。这种能力有助于API设计者构建更有弹性的代码。
  • 移除实验性的AOT和JIT编译器,它的使用量很小,但需要大量的维护工作。该计划要求维护Java级别的JVM编译器接口,以便开发人员可以继续使用外部构建的编译器版本进行JIT编译。AOT编译(jaotc工具)作为一项实验性功能被纳入JDK 9。该工具使用Graal编译器,它本身是用Java编写的,用于AOT编译。这些实验性功能没有包括在Oracle发布的JDK 16构建中,也没有人抱怨。根据规定的计划,三个JDK模块将被删除:jdk.aot(jaotc工具);internal.vm.compiler,Graal编译器;和jdk.internal.vm.compiler.management,Graal MBean。与AOT编译相关的HotSpot代码也将被删除。
  • 将JDK移植到MacOS/AArch64,以响应苹果公司将其Macintosh计算机从x64过渡到AArch64的计划。一个用于Java的AArch64移植已经存在于Linux,而用于Windows的工作正在进行中。Java 开发者希望通过采用条件编译的方式,从这些移植中重新使用现有的AArch64代码,就像JDK的移植一样,以适应低级惯例的差异,如应用程序二进制接口和保留的处理器寄存器集。为 MacOS/AArch64 所做的修改有可能破坏现有的 Linux/AArch64、Windows/AArch64 和 MacOS/x64 port, 但这种风险将通过集成前的测试来降低。
  • 废弃Applet API的删除。这个API基本上是无关紧要的,因为所有的网络浏览器供应商要么已经删除了对Java浏览器插件的支持,要么已经宣布计划这样做。此前,Applet API在2017年9月的Java 9中已被废弃,但不是为了删除。
  • 一个新的MacOS渲染管道,使用Apple Metal API作为现有管道的替代品,该管道使用已废弃的OpenGL API。这项建议旨在为Java 2D API提供一个功能完备的渲染管道,该管道使用MacOS Metal框架,并在苹果公司从未来的MacOS版本中移除OpenGL API的情况下做好准备。该管道旨在与现有的OpenGL管道具有同等的功能,在选定的应用程序和基准测试中具有相同或更好的性能。一个干净的架构将被创建,适合当前的Java 2D模型。该管道将与OpenGL管道共存,直到被淘汰。本提案的目标不是要增加任何新的Java或JDK APIs。
  • 增强的伪随机数生成器将为伪随机数生成器(PRNGs)提供新的接口类型和实现,包括可跳转的PRNGs和另外一类可分割的PRNG算法(LXM)。一个新的接口,RandomGenerator,将为所有现有的和新的PRNGs提供一个统一的API。四个专门的RandomGenerator接口将被提供。该计划的动机是关注Java中伪随机数生成领域的多个改进领域。这项工作并不要求提供众多其他PRNG算法的实现。但是增加了三种常见的算法,这些算法已经广泛部署在其他编程语言环境中。该计划的目标包括
    • 使得在应用中互换使用各种PRNG算法变得更加容易。
    • 改进对基于流的编程的支持,提供PRNG对象的流。
    • 消除了现有PRNG类中的代码重复。
    • 保留了java.util.Random.Category的现有行为。

感谢观看,如果您有兴趣,可以关注一下我,方便查看后续文章,一起学习,共同进步,不胜感激!

Guess you like

Origin juejin.im/post/7034674963932151816