New Features in Java 14 – Java 14中的新功能

最后修改: 2020年 12月 21日

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

1. Overview

1.概述

Java 14 released on March 17, 2020, exactly six months after its previous version as per Java’s new release cadence.

Java 14于2020年3月17日发布,按照Java的新版本发布节奏,在其上一版本之后正好六个月。

In this tutorial, we’ll look at a summary of new and deprecated features of version 14 of the language.

在本教程中,我们将看一下第14版语言的新功能和废弃功能的总结

We also have more detailed articles on Java 14 that offer an in-depth view of the new features.

我们还有更详细的文章关于Java 14,对新功能进行了深入介绍。

2. Features Carried Over From Earlier Versions

2.从早期版本继承下来的功能

A few features have been carried over in Java 14 from the previous version. Let’s look at them one by one.

在Java 14中,有一些功能是从上一版本中延续下来的。让我们逐一来看看。

2.1. Switch Expressions (JEP 361)

2.1.开关表达式(JEP 361

These were first introduced as a preview feature in JDK 12, and even in Java 13, they continued as preview features only. But now, switch expressions have been standardized so that they are part and parcel of the development kit.

这些功能最早是在JDK 12中作为预览功能引入的,甚至在Java 13中,它们仍然只是作为预览功能。但是现在,switch expressions已经被标准化,因此它们是开发工具包的组成部分

What this effectively means is that this feature can now be used in production code, and not just in the preview mode to be experimented with by developers.

这实际上意味着,这一功能现在可以在生产代码中使用,而不仅仅是在预览模式下由开发人员进行试验。

As a simple example, let’s consider a scenario where we’d designate days of the week as either weekday or weekend.

作为一个简单的例子,让我们考虑这样一种情况:我们把一周的日子指定为工作日或周末。

Prior to this enhancement, we’d have written it as:

在这项改进之前,我们会把它写成。

boolean isTodayHoliday;
switch (day) {
    case "MONDAY":
    case "TUESDAY":
    case "WEDNESDAY":
    case "THURSDAY":
    case "FRIDAY":
        isTodayHoliday = false;
        break;
    case "SATURDAY":
    case "SUNDAY":
        isTodayHoliday = true;
        break;
    default:
        throw new IllegalArgumentException("What's a " + day);
}

With switch expressions, we can write the same thing more succinctly:

通过切换表达式,我们可以更简洁地写出同样的东西。

boolean isTodayHoliday = switch (day) {
    case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> false;
    case "SATURDAY", "SUNDAY" -> true;
    default -> throw new IllegalArgumentException("What's a " + day);
};

2.2. Text Blocks (JEP 368)

2.2. 文本块(JEP 368

Text blocks continue their journey to getting a mainstream upgrade and are still available as preview features.

文本块继续其获得主流升级的旅程,并且仍然可以作为预览功能使用。

In addition to the capabilities from JDK 13 to make multiline strings easier to use, in their second preview, text blocks now have two new escape sequences:

除了JDK 13提供的使多行字符串更容易使用的功能外,在其第二次预览中,文本块现在有两个新的转义序列

  • \: to indicate the end of the line, so that a new line character is not introduced
  • \s: to indicate a single space

For example:

比如说。

String multiline = "A quick brown fox jumps over a lazy dog; the lazy dog howls loudly.";

can now be written as:

现在可以写成。

String multiline = """
    A quick brown fox jumps over a lazy dog; \
    the lazy dog howls loudly.""";

This improves the readability of the sentence for a human eye but does not add a new line after dog;.

这提高了该句子对人眼的可读性,但没有在dog;后面增加一个新行。

3. New Preview Features

3.新的预览功能

3.1. Pattern Matching for instanceof (JEP 305)

3.1.instanceof的模式匹配(JEP 305

JDK 14 has introduced pattern matching for instanceof with the aim of eliminating boilerplate code and make the developer’s life a little bit easy.

JDK 14为instanceof引入了模式匹配,目的是消除模板代码,让开发者的生活变得简单一些。

To understand this, let’s consider a simple example.

为了理解这一点,让我们考虑一个简单的例子。

Before this feature, we wrote:

在这个功能之前,我们写道。

if (obj instanceof String) {
    String str = (String) obj;
    int len = str.length();
    // ...
}

Now, we don’t need as much code to start using obj as String:

现在,我们不需要那么多代码就可以开始使用obj作为String。

if (obj instanceof String str) {
    int len = str.length();
    // ...
}

In future releases, Java is going to come up with pattern matching for other constructs such as a switch.

在未来的版本中,Java将为其他结构体(如switch)提供模式匹配。

3.2. Records (JEP 359)

3.2. 记录(JEP 359

Records were introduced to reduce repetitive boilerplate code in data model POJOs. They simplify day to day development, improve efficiency and greatly minimize the risk of human error.

记录的出现是为了减少数据模型POJO中重复的模板代码。它们简化了日常开发,提高了效率,并大大降低了人为错误的风险

For example, a data model for a User with an id and password can be simply defined as:

例如,一个有idpasswordUser的数据模型可以简单地定义为。

public record User(int id, String password) { };

As we can see, we are making use of a new keyword, record, here. This simple declaration will automatically add a constructor, getters, equals, hashCode and toString methods for us.

我们可以看到,我们正在使用一个新的关键字,record,这里。这个简单的声明将自动为我们添加一个构造函数、getters、equalshashCodetoString方法。

Let’s see this in action with a JUnit:

让我们用JUnit来看看这个动作。

private User user1 = new User(0, "UserOne");

@Test
public void givenRecord_whenObjInitialized_thenValuesCanBeFetchedWithGetters() {
    assertEquals(0, user1.id());
    assertEquals("UserOne", user1.password());
}

@Test
public void whenRecord_thenEqualsImplemented() {
    User user2 = user1;
    assertTrue(user1, user2);
}

@Test
public void whenRecord_thenToStringImplemented() {
    assertTrue(user1.toString().contains("UserOne"));
}

4. New Production Features

4.新的生产特点

Along with the two new preview features, Java 14 has also shipped a concrete production-ready one.

除了这两个新的预览功能外,Java 14还交付了一个具体的可用于生产的功能。

4.1. Helpful NullPointerExceptions (JEP 358)

4.1.有帮助的NullPointerExceptions (JEP 358)

Previously, the stack trace for a NullPointerException didn’t have much of a story to tell except that some value was null at a given line in a given file.

以前,NullPointerException的堆栈跟踪并没有太多的故事可讲,只是说某个文件的某一行的某个值为空。

Though useful, this information only suggested a line to debug instead of painting the whole picture for a developer to understand, just by looking at the log.

虽然很有用,但这些信息只是建议了一个行的调试,而不是为开发人员描绘了一幅完整的图画,只是通过看日志就能理解。

Now Java has made this easier by adding the capability to point out what exactly was null in a given line of code.

现在,Java已经通过增加指出某一行代码中到底是什么null的功能,使之更容易

For example, consider this simple snippet:

例如,考虑这个简单的片段。

int[] arr = null;
arr[0] = 1;

Earlier, on running this code, the log would say:

早些时候,在运行这段代码时,日志会显示。

Exception in thread "main" java.lang.NullPointerException
at com.baeldung.MyClass.main(MyClass.java:27)

But now, given the same scenario, the log might say:

但现在,在同样的情况下,日志可能会说。

java.lang.NullPointerException: Cannot store to int array because "a" is null

As we can see, now we know precisely which variable caused the exception.

正如我们所看到的,现在我们确切地知道是哪个变量导致了这个异常。

5. Incubating Features

5.孵化的特点

These are the non-final APIs and tools that the Java team comes up with, and provides us for experimentation. They are different from preview features and are provided as separate modules in the package jdk.incubator.

这些是Java团队想出的非最终的API和工具,并提供给我们进行实验。它们与预览版的功能不同,是作为包jdk.incubator中的独立模块提供的。

5.1. Foreign Memory Access API (JEP 370)

5.1.外国内存访问API(JEP 370

This is a new API to allow Java programs to access foreign memory, such as native memory, outside the heap in a safe and efficient manner.

这是一个新的API,允许Java程序以安全、高效的方式访问堆外的外国内存,如本地内存。

Many Java libraries such as mapDB and memcached do access foreign memory and it was high time the Java API itself offered a cleaner solution. With this intention, the team came up with this JEP as an alternative to its already existing ways to access non-heap memory – ByteBuffer API and sun.misc.Unsafe API.

许多Java库,如mapDBmemcached都会访问外来内存,现在是Java API本身提供一个更清洁的解决方案的时候了。本着这一意图,该团队提出了这个JEP,作为已经存在的访问非堆内存的方法–ByteBuffer API和sun.misc.Unsafe API的替代品。

Built upon three main abstractions of MemorySegment, MemoryAddress and MemoryLayout, this API is a safe way to access both heap and non-heap memory.

该API建立在MemorySegmentMemoryAddressMemoryLayout三个主要抽象之上,是访问堆和非堆内存的安全方式。

5.2. Packaging Tool (JEP 343)

5.2. 包装工具(JEP 343

Traditionally, to deliver Java code, an application developer would simply send out a JAR file that the user was supposed to run inside their own JVM.

传统上,为了传递Java代码,应用程序开发人员会简单地发送一个JAR文件,让用户在自己的JVM中运行。

However, users rather expected an installer that they’d double click to install the package on their native platforms, such as Windows or macOS.

然而,用户更期望有一个安装程序,他们可以双击安装包在他们的原生平台,如Windows或macOS。

This JEP aims to do precisely that. Developers can use jlink to condense the JDK down to the minimum required modules, and then use this packaging tool to create a lightweight image that can be installed as an exe on Windows or a dmg on a macOS.

这个JEP的目的正是要做到这一点。开发人员可以使用jlink将JDK压缩到所需的最小模块,然后使用这个打包工具创建一个轻量级的镜像,可以在Windows上作为exe安装,或者在MacOS上作为dmg

6. JVM/HotSpot Features

6.JVM/HotSpot功能

6.1. ZGC on Windows (JEP 365) and macOS (JEP 364) – Experimental

6.1. Windows(JEP 365)和macOS(JEP 364)上的ZGC – 试验性的

The Z Garbage Collector, a scalable, low-latency garbage collector, was first introduced in Java 11 as an experimental feature. But initially, the only supported platform was Linux/x64.

Z垃圾收集器是一个可扩展的、低延迟的垃圾收集器,在Java 11中首次作为一个实验性功能被引入。但最初,唯一支持的平台是Linux/x64。

After receiving positive feedback on ZGC for Linux, Java 14 has ported its support to Windows and macOS as well. Though still an experimental feature, it’s all set to become production-ready in the next JDK release.

在收到针对 Linux 的 ZGC 的积极反馈后,Java 14 也将其支持移植到了 Windows 和 macOS。尽管它仍然是一项实验性功能,但在下一个 JDK 版本中,它将成为可以投入生产的功能。

6.2. NUMA-Aware Memory Allocation for G1 (JEP 345)

6.2.G1的NUMA感知内存分配(JEP 345

Non-uniform memory access (NUMA) was not implemented so far for the G1 garbage collector, unlike the Parallel collector.

到目前为止,G1垃圾收集器没有实现非统一内存访问(NUMA),与并行收集器不同。

Looking at the performance improvement that it offers to run a single JVM across multiple sockets, this JEP was introduced to make the G1 collector NUMA-aware as well.

考虑到在多个套接字上运行单个JVM所带来的性能提升,引入这个JEP是为了让G1收集器也能感知NUMA

At this point, there’s no plan to replicate the same to other HotSpot collectors.

在这一点上,没有计划将同样的东西复制到其他热点收集器上。

6.3. JFR Event Streaming (JEP 349)

6.3. JFR事件流(JEP 349

With this enhancement, JDK’s flight recorder data is now exposed so that it can be continuously monitored. This involves modifications to the package jdk.jfr.consumer so that users can now read or stream the recording data directly.

通过这项改进,JDK的飞行记录器数据现在被暴露出来,从而可以持续监控。这涉及到对包jdk.jfr.consumer的修改,因此用户现在可以直接读取或流化记录数据。

7. Deprecated or Removed Features

7.废弃或删除的功能

Java 14 has deprecated a couple of features:

Java 14已经废弃了一些功能。

  • Solaris and SPARC Ports (JEP 362) – because this Unix operating system and RISC processor are not in active development since the past few years
  • ParallelScavenge + SerialOld GC Combination (JEP 366) – since this is a rarely used combination of GC algorithms, and requires significant maintenance effort

There are a couple of removals as well:

也有几个人被免职。

  • Concurrent Mark Sweep (CMS) Garbage Collector (JEP 363) – deprecated by Java 9, this GC has been succeeded by G1 as the default GC. Also, there are other more performant alternatives to use now, such as ZGC and Shenandoah, hence the removal
  • Pack200 Tools and API (JEP 367) – these were deprecated for removal in Java 11, and now removed

8. Conclusion

8.结语

In this tutorial, we looked at the various JEPs of Java 14.

在本教程中,我们研究了Java 14的各种JEPs。

In all, there are 16 major features in this release of the language, including preview features, incubators, deprecations and removals. We looked at all of them one by one, and the language features with examples.

总的来说,这个版本的语言有16个主要特征,包括预览特征、孵化器、弃用和移除。我们逐一查看了所有这些功能,以及带有实例的语言功能。

As always, the source code is available over on GitHub.

像往常一样,源代码可在GitHub上获得