New Features in Java 17 – Java 17的新功能

最后修改: 2021年 11月 7日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll talk about the news related to the new version of the Java ecosystem, Java SE 17, including the new features and the changes in its release process, LTS support and licenses.

在本教程中,我们将谈论与Java生态系统的新版本Java SE 17有关的新闻,包括新功能以及其发布流程、LTS支持和许可的变化。

2. List of JEPs

2.JEPs名单

First, let’s talk about what can affect the everyday work in the life of Java developers.

首先,我们来谈谈什么会影响到Java开发人员的日常工作。

2.1. Restore Always-Strict Floating-Point Semantics (JEP 306)

2.1.恢复始终严格的浮点语义(JEP 306

This JEP is mainly for scientific applications, and it makes floating-point operations consistently strict. The default floating-point operations are strict or strictfp, both of which guarantee the same results from the floating-point calculations on every platform.

这个JEP主要用于科学应用,它使浮点运算始终保持严格。默认的浮点运算是strictstrictfp,两者都能保证在每个平台上的浮点计算结果相同。

Before Java 1.2, strictfp behavior was the default one as well. However, because of hardware issues, the architects changed, and the keyword strictfp was necessary to re-enable such behavior. So, there is no need to use this keyword anymore.

在Java 1.2之前,strictfp行为也是默认行为。然而,由于硬件问题,架构师发生了变化,需要使用关键字strictfp来重新启用这种行为。所以,现在不需要再使用这个关键字了。

2.2. Enhanced Pseudo-Random Number Generators (JEP 356)

2.2.增强型伪随机数生成器(JEP 356)

Also related to more special use cases, JEP 356 provides new interfaces and implementations for Pseudo-Random Number Generators (PRNG).

同样与更多的特殊用例有关,JEP 356为伪随机数生成器(PRNG)提供了新的接口和实现。

So, it’s easier to use different algorithms interchangeably, and it also offers better support for stream-based programming:

所以,它更容易互换使用不同的算法,而且它还为基于流的编程提供了更好的支持。

public IntStream getPseudoInts(String algorithm, int streamSize) {
    // returns an IntStream with size @streamSize of random numbers generated using the @algorithm
    // where the lower bound is 0 and the upper is 100 (exclusive)
    return RandomGeneratorFactory.of(algorithm)
            .create()
            .ints(streamSize, 0,100);
}

Legacy random classes, such as java.util.Random, SplittableRandom and SecureRandom now extend the new RandomGenerator interface.

传统的随机类,如java.util.RandomSplittableRandomSecureRandom现在扩展了新的RandomGenerator接口。

2.3. New macOS Rendering Pipeline (JEP 382)

2.3. 新的macOS渲染管道(JEP 382

This JEP implements a Java 2D internal rendering pipeline for macOS since Apple deprecated the OpenGL API (in macOS 10.14), used internally in Swing GUI. The new implementation uses the Apple Metal API, and apart from the internal engine, there were no changes to the existing APIs.

这个JEP为macOS实现了一个Java 2D内部渲染管道,因为苹果公司已经废弃了OpenGL API(在macOS 10.14中),在Swing GUI中内部使用。新的实现使用了Apple Metal API,除了内部引擎外,对现有的API没有任何改变。

2.4. macOS/AArch64 Port (JEP 391)

2.4. macOS/AArch64端口(JEP 391

Apple announced a long-term plan to transition its computer line from X64 to AArch64. This JEP ports the JDK to run on AArch64 in macOS platforms.

苹果公司宣布了一项长期计划,将其计算机产品线从X64过渡到AArch64。这个JEP将JDK移植到MacOS平台的AArch64上运行。

2.5. Deprecate the Applet API for Removal (JEP 398)

2.5.废弃Applet API的删除(JEP 398>)

Although this may be sad for many Java developers who started their development career using Applet APIs, many web browsers have already removed their support for Java plugins. As the API became irrelevant, this version marked it for removal even though it has been marked as deprecated since version 9.

尽管这对许多使用Applet API开始他们的开发生涯的Java开发者来说可能很难过,但许多网络浏览器已经取消了对Java插件的支持。由于该API变得无关紧要,这个版本将其标记为删除,尽管它从第9版开始就被标记为废弃。

2.6. Strongly Encapsulate JDK Internals (JEP 403)

2.6.强化封装JDK内部(JEP 403

JEP 403 represents one more step toward strongly encapsulating JDK internals since it removes the flag –illegal-access. The platform will ignore the flag, and if the flag is present, the console will issue a message informing the discontinuation of the flag.

JEP 403代表了向强封装JDK内部的又一步骤,因为它删除了标志-illegal-access。平台将忽略该标志,如果该标志存在,控制台将发出一条消息,告知该标志的终止。

This feature will prevent JDK users from accessing internal APIs, except for critical ones like sun.misc.Unsafe.

该功能将阻止JDK用户访问内部API,除了像sun.misc.Unsafe这样的关键API。

2.7. Pattern Matching for Switch (Preview) (JEP 406)

2.7.开关的模式匹配(预览)(JEP 406)

This is another step toward pattern matching by enhancing pattern matching for switch expressions and statements. It reduces the boilerplate necessary to define those expressions and improves the expressiveness of the language.

这是通过加强switch表达式和语句的模式匹配而向模式匹配迈出的另一步。它减少了定义这些表达式所需的模板,提高了语言的表现力。

Let’s see two examples of the new capabilities:

让我们看看新功能的两个例子。


static record Human (String name, int age, String profession) {}

public String checkObject(Object obj) {
    return switch (obj) {
        case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession());
        case Circle c -> "This is a circle";
        case Shape s -> "It is just a shape";
        case null -> "It is null";
        default -> "It is an object";
    };
}

public String checkShape(Shape shape) {
    return switch (shape) {
        case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle";
        case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle";
        default -> "Just a normal shape";
    };
}

2.8. Remove RMI Activation (JEP 407)

2.8. 删除RMI激活(JEP 407

Marked for removal in version 15, this JEP removed the RMI activation API from the platform in version 17.

该JEP在第15版中被标记为删除,在第17版中从平台中删除了RMI激活API。

2.9. Sealed Classes (JEP 409)

2.9.封闭类(JEP 409

Sealed classes are part of Project Amber, and this JEP officially introduces a new feature to the language, although it was available in preview mode in the JDK versions 15 and 16.

密封类是Project Amber的一部分,这个JEP正式为语言引入了一个新特性,尽管它在JDK版本1516中是以预览模式提供。

The feature restricts which other classes or interfaces may extend or implement a sealed component. Showing another improvement related to pattern matching combined with the JEP 406 will allow a more sophisticated and cleaner inspection of the type, cast and act code pattern.

该功能限制了哪些其他类或接口可以扩展或实现一个密封的组件。显示另一个与模式匹配有关的改进,结合JEP 406,将允许对类型、cast和act代码模式进行更复杂和更干净的检查。

Let’s see it in action:

让我们看看它的行动。


int getNumberOfSides(Shape shape) {
    return switch (shape) {
        case WeirdTriangle t -> t.getNumberOfSides();
        case Circle c -> c.getNumberOfSides();
        case Triangle t -> t.getNumberOfSides();
        case Rectangle r -> r.getNumberOfSides();
        case Square s -> s.getNumberOfSides();
    };
}

2.10. Remove the Experimental AOT and JIT Compiler (JEP 410)

2.10.删除实验性AOT和JIT编译器(JEP 410

Introduced into JDK 9 and JDK 10, respectively, as experimental features, the Ahead-Of-Time (AOT) compilation (JEP 295) and Just-In-Time (JIT) compiler from GraalVM (JEP-317) were features with a high cost of maintenance.

分别作为实验性功能引入JDK 9和JDK 10的超前(AOT)编译(JEP 295)和来自GraalVM的即时(JIT)编译器(JEP-317)是具有高维护成本的功能。

On the other hand, they had no significant adoption. Because of that, this JEP removed them from the platform, but developers can still leverage them using GraalVM.

另一方面,它们没有被大量采用。正因为如此,该JEP将它们从平台中移除,但开发人员仍然可以使用GraalVM来利用它们。

2.11. Deprecate the Security Manager for Removal (JEP 411)

2.11.撤消安全管理器的使用(JEP 411

The security manager aimed to secure client-side Java code is yet another feature marked for removal due to not being relevant anymore.

旨在确保客户端Java代码安全的安全管理器是另一个被标记为删除的功能,因为它不再有意义。

2.12. Foreign Function and Memory API (Incubator) (JEP 412)

2.12.外国函数和内存API(孵化器)(JEP 412

The Foreign Function and Memory API allow Java developers to access code from outside the JVM and manage memory out of the heap. The goal is to replace the JNI API and improve the security and performance compared to the old one.

外来函数和内存 API 允许 Java 开发人员从 JVM 外部访问代码并管理堆外的内存。其目的是取代JNI API,并与旧的API相比提高安全性和性能。

This API is another feature developed by Project Panama, and it has been evolved and predeceased by JEPs 393, 389, 383 and 370.

这个API是由巴拿马项目开发的另一个功能,它已经被393389383370的JEP演化和先入为主。

With this feature, we can make a call to a C library from a Java class:

有了这个功能,我们可以从一个Java类中调用一个C库。


private static final SymbolLookup libLookup;

static {
    // loads a particular C library
    var path = JEP412.class.getResource("/print_name.so").getPath();
    System.load(path);
    libLookup = SymbolLookup.loaderLookup();
}

First, it is necessary to load the target library we wish to invoke via the API.

首先,有必要加载我们希望通过API调用的目标库。

Next, we need to specify the signature of the target method and finally call it:

接下来,我们需要指定目标方法的签名,最后调用它。


public String getPrintNameFormat(String name) {

    var printMethod = libLookup.lookup("printName");

    if (printMethod.isPresent()) {
        var methodReference = CLinker.getInstance()
            .downcallHandle(
                printMethod.get(),
                MethodType.methodType(MemoryAddress.class, MemoryAddress.class),
                FunctionDescriptor.of(CLinker.C_POINTER, CLinker.C_POINTER)
            );

        try {
            var nativeString = CLinker.toCString(name, newImplicitScope());
            var invokeReturn = methodReference.invoke(nativeString.address());
            var memoryAddress = (MemoryAddress) invokeReturn;
            return CLinker.toJavaString(memoryAddress);
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        }
    }
    throw new RuntimeException("printName function not found.");
}

2.13. Vector API (Second Incubator) (JEP 414)

2.13.向量API(第二孵化器)(JEP 414

The Vector API deals with the SIMD (Single Instruction, Multiple Data) type of operation, meaning various sets of instructions executed in parallel. It leverages specialized CPU hardware that supports vector instructions and allows the execution of such instructions as pipelines.

矢量API处理SIMD(单指令,多数据)类型的操作,意味着各种指令集的并行执行。它利用了支持矢量指令的专门的CPU硬件,并允许以流水线的方式执行此类指令。

As a result, the new API will enable developers to implement more efficient code, leveraging the potential of the underlying hardware.

因此,新的API将使开发者能够实现更有效的代码,利用底层硬件的潜力。

Everyday use cases for this operation are scientific algebra linear applications, image processing, character processing, and any heavy arithmetic application or any application that needs to apply an operation for multiple independent operands.

这种操作的日常用例是科学代数线性应用、图像处理、字符处理,以及任何重型算术应用或任何需要对多个独立操作数进行操作的应用。

Let’s use the API to illustrate a simple vector multiplication example:

让我们用API来说明一个简单的矢量乘法例子。


public void newVectorComputation(float[] a, float[] b, float[] c) {
    for (var i = 0; i < a.length; i += SPECIES.length()) {
        var m = SPECIES.indexInRange(i, a.length);
        var va = FloatVector.fromArray(SPECIES, a, i, m);
        var vb = FloatVector.fromArray(SPECIES, b, i, m);
        var vc = va.mul(vb);
        vc.intoArray(c, i, m);
    }
}

public void commonVectorComputation(float[] a, float[] b, float[] c) {
    for (var i = 0; i < a.length; i ++) {
        c[i] = a[i] * b[i];
    }
}

2.14. Context-Specific Deserialization Filters (JEP 415)

2.14.特定情境的反序列化过滤器(JEP 415

JEP 290, first introduced in JDK 9, enabled us to validate incoming serialized data from untrusted sources, a common source of many security issues. That validation happens at the JVM level, giving more security and robustness.

JEP 290,首次在 JDK 9 中引入,使我们能够验证来自不可信任的来源的传入序列化数据,这是许多安全问题的常见来源。这种验证发生在JVM级别,提供了更多的安全性和健壮性。

With JEP 415, applications can configure context-specific and dynamically selected deserialization filters defined at the JVM level. Each deserialization operation will invoke such filters.

通过JEP 415,应用程序可以配置在JVM层面上定义的特定于上下文和动态选择的反序列化过滤器。每个反序列化操作都会调用这种过滤器。

3. LTS Definition

3.LTS的定义

The changes don’t stay only in the code — processes are changing as well.

变化不只停留在代码上–流程也在变化。

Java platform releases have a widely known history of being long and imprecise. Despite being designed to have a three-year cadence between releases, it often became a four-year process.

Java平台的发布有一个广为人知的漫长而不精确的历史。尽管在设计上是以三年为一个发布周期,但它往往成为一个四年的过程。

Moreover, given the new dynamic of the market where innovation and quick response became obligatory, the team responsible for the platform’s evolution decided to change the release cadence to adapt to the new reality.

此外,鉴于市场的新动态,创新和快速反应成为必须,负责平台发展的团队决定改变发布节奏以适应新的现实。

As a result, a new six-month feature-release model has been adopted since Java 10 (released on March 20, 2018).

因此,自Java 10(2018年3月20日发布)以来,采用了新的六个月功能发布模式。

3.1. Six-Month Feature-Release Model

3.1.6个月的功能发布模式

The new six-month feature-release model allows the platform developers to release features when they are ready. This removes the pressure of pushing the feature into the release. Otherwise, they would have to wait three to four years to make the feature available to the platform’s users.

新的六个月功能发布模式允许平台开发人员在准备好时发布功能。这消除了将功能推入发布的压力。否则,他们将不得不等待三到四年才能向平台的用户提供该功能。

The new model also improves the feedback cycle between users and the platform’s architects. That’s because features can be made available in an incubating mode and only released for general use after several interactions.

新模式还改善了用户和平台架构师之间的反馈周期。这是因为功能可以在孵化模式下提供,只有在经过几次互动后才会被释放出来供大家使用。

3.2. LTS Model

3.2. LTS模型

Since enterprise applications widely use Java, stability is critical. Besides, it’s costly to keep supporting and providing patch updates to all these versions.

由于企业应用广泛使用Java,稳定性至关重要。此外,持续支持和提供所有这些版本的补丁更新是很昂贵的。

For this reason, the Long-Term Support (LTS) versions were created, offering users extended support. So, such versions naturally become more stable and secure due to bug fixes, performance improvements and security patches. In the case of Oracle, this support usually lasts for eight years.

出于这个原因,长期支持(LTS)版本应运而生,为用户提供扩展支持。因此,由于错误修复、性能改进和安全补丁,这类版本自然变得更加稳定和安全。就甲骨文而言,这种支持通常持续8年。

Since the introduction of the changes in the release model, the LTS versions were Java SE 11 (released in September 2018) and Java SE 17 (released in September 2021). Nonetheless, version 17 brought something new to the model. In short, the interval between LTS versions is now two years instead of three, making Java 21 (planned for September 2023) probably the next LTS.

自从引入发布模式的变化后,LTS版本是Java SE 11(2018年9月发布)和Java SE 17(2021年9月发布)。尽管如此,17版还是给该模型带来了一些新的东西。简而言之,LTS版本之间的间隔现在是两年而不是三年,这使得Java 21(计划于2023年9月)可能成为下一个LTS。

Another point worth mentioning is that this release model is not new. It was copied shamelessly and adapted from other projects such as Mozilla Firefox, Ubuntu and others where the model proved itself.

另一点值得一提的是,这种发布模式并不新鲜。它被无耻地复制和改编自其他项目,如Mozilla Firefox、Ubuntu和其他项目,在这些项目中该模式证明了自己。

4. New Release Process

4.新的发布过程

We based this article on the JEP 3, given that it describes all changes in the process. Please check it for further details. We’ll try to provide a concise summary of it here.

我们以JEP 3为基础编写了这篇文章,因为它描述了流程中的所有变化。请查看它以了解进一步的细节。我们将尝试在这里提供一个简洁的总结。

Given the new model described above, combined with the continuous development of the platform and the new six-month release cadences (generally June and December), Java will move faster. The development team of the JDK will initiate the release cycle for the next feature release following the process described next.

鉴于上述的新模式,结合平台的持续发展和新的六个月的发布周期(一般是六月和十二月),Java的发展速度会更快。JDK的开发团队将按照接下来描述的流程启动下一个功能版本的发布周期。

The process begins with the fork of the main-line. Then the development continues in a stabilization repository, JDK/JDK$N (for example, JDK17). There, the development continues focusing on the stabilization of the release.

这个过程从主线的分叉开始。然后在一个稳定库中继续开发,即JDK/JDK$N(例如,JDK17)。在那里,开发工作继续专注于稳定化版本。

Before we delve deeper into the process, let’s clarify some terminology:

在我们深入研究这个过程之前,让我们先澄清一些术语。

  • Bugs: In this context, bugs means tickets or tasks:
    • Current: These are either actual bugs related to the current version (the new one about to be released) or adjustments to new features already included in this version (new JEPs).
    • Targeted: Related to the older versions and planned to be fixed or addressed in this new version
  •  Priorities: Ranging from P1 to P5, where P1 is the most important, with the importance progressively diminishing down to P5

4.1. New Format

4.1.新格式

The stabilization process proceeds for the next three months:

在接下来的三个月里,稳定过程继续进行。

  • The JDK/JDK$N repository works like a release branch, and at this point, no new JEPs of new JEPs go into the repository.
  • Next, the developments in this repository will be stabilized and ported to the main-line where other developments continue.
  • Ramp Down Phase 1 (RDP 1): Lasts between four and five weeks. Developers drop all currents P4-P5 and the targeted P1-P3 (depending on deferring, fix or enhancement). This means that P5+ test/docs bugs and targeted P3+ code bugs are optional.
  • Ramp Down Phase 2 (RDP 2): Lasts between three and four weeks. Now they postpone all currents P3-P5 and the targeted P1-P3 (depending on deferring, fix or enhancement).
  • Finally, the team publishes a release candidate build and makes it available to the public. This phase lasts between two and five weeks, and only current P1 fixes are addressed (using fix).

Once all those cycles finish, the new release becomes the General Availability (GA) version.

一旦所有这些周期结束,新版本就成为通用版本(GA)。

5. What Is Next?

5.下一步是什么?

JDK architects continue working on many projects that aim to modernize the platform. The goal is to provide a better development experience and more robust and performant APIs.

JDK 架构师继续在许多项目上工作,旨在使平台现代化。目标是提供更好的开发体验和更强大、更高性能的API。

As a result, the JDK 18 should be out six months from now, although this version is not likely to contain significant or disruptive changes. We can follow the list of proposed JEPs targeted for this version in the official OpenJDK project portal.

因此,JDK 18应该会在六个月后问世,尽管这个版本不可能包含重大或破坏性的变化。我们可以在官方的OpenJDK项目门户中关注针对该版本的拟议JEP列表。

Another relevant piece of news that affects the current and future versions is the new no-fee terms and conditions license applied to the Oracle JDK distribution (or Hotspot). For most cases, Oracle offers its distribution free of cost for production and other environments, but there are a few exceptions. Again, please refer to the link.

另一个影响当前和未来版本的相关消息是适用于Oracle JDK发行版(或Hotspot)的新不收费条款和条件许可。对于大多数情况,Oracle为生产和其他环境免费提供其发行版,但也有少数例外情况。同样,请参考该链接。

As mentioned before, the new process targets the next LTS version to be version 21, and the plan is to release it by September 2023.

如前所述,新进程的目标是将下一个LTS版本定为21版,计划在2023年9月前发布。

6. Conclusion

6.结语

In this article, we looked at the news about the new Java 17 version, going through its recent developments, new capabilities, support definition and release cycle process.

在这篇文章中,我们看了关于新的Java 17版本的新闻,经历了它的最新发展、新功能、支持定义和发布周期过程。

As usual, all code samples used in this article are available over on GitHub.

像往常一样,本文中使用的所有代码样本都可以在GitHub上找到