Pattern Matching for instanceof in Java 14 – Java 14中instanceof的模式匹配

最后修改: 2020年 3月 5日

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

1. Overview

1.概述

In this quick tutorial, we’ll continue our series on Java 14 by taking a look at Pattern Matching for instanceof which is another new preview feature included with this version of the JDK.

在这个快速教程中,我们将继续我们的Java 14系列,看看instanceof的模式匹配,这是这个版本的JDK包含的另一个新预览功能。

In summary, JEP 305 aims to make the conditional extraction of components from objects much simpler, concise, readable and secure.

综上所述,JEP 305旨在使从对象中提取组件的条件更加简单、简洁、可读和安全。

2. Traditional instanceOf Operator

2.传统的instanceOf操作者

At some point, we’ve probably all written or seen code that includes some kind of conditional logic to test if an object has a specific type. Typically, we might do this with the instanceof operator followed by a cast. This allows us to extract our variable before applying further processing specific to that type.

在某些时候,我们可能都写过或看过一些代码,其中包括某种条件逻辑来测试一个对象是否具有特定的类型。通常情况下,我们可能会使用instanceof操作符,然后是cast这允许我们在应用针对该类型的进一步处理之前提取我们的变量。

Let’s imagine we want to check the type in a simple hierarchy of animal objects:

让我们设想一下,我们想在一个简单的动物对象的层次结构中检查其类型。

if (animal instanceof Cat) {
    Cat cat = (Cat) animal;
    cat.meow();
   // other cat operations
} else if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.woof();
    // other dog operations
}

// More conditional statements for different animals

In this example, for each conditional block, we’re testing the animal parameter to determine its type, converting it via a cast and declaring a local variable. Then, we can perform operations specific to that particular animal.

在这个例子中,对于每个条件块,我们都要测试动物参数以确定其类型,通过转换和声明一个局部变量。然后,我们可以执行针对该特定动物的操作。

Although this approach works, it has several drawbacks:

虽然这种方法可行,但它有几个缺点。

  • It’s tedious to write this type of code where we need to test the type and make a cast for every conditional block
  • We repeat the type name three times for every if block
  • Readability is poor as the casting and variable extraction dominate the code
  • Repeatedly declaring the type name means there’s more likelihood of introducing an error. This could lead to an unexpected runtime error
  • The problem magnifies itself each time we add a new animal

In the next section, we’ll take a look at what enhancements Java 14 provides to address these shortcomings.

在下一节中,我们将看看Java 14提供了哪些增强功能来解决这些缺陷。

3. Enhanced instanceOf in Java 14

3.Java 14中增强的instanceOf

Java 14, via JEP 305, brings an improved version of the instanceof operator that both tests the parameter and assigns it to a binding variable of the proper type.

Java 14通过JEP 305带来了一个改进版的instanceof操作符,它既能测试参数,又能将其分配给一个适当类型的绑定变量。

This means we can write our previous animal example in a much more concise way:

这意味着我们可以用一种更简洁的方式来写我们之前的动物例子

if (animal instanceof Cat cat) {
    cat.meow();
} else if(animal instanceof Dog dog) {
    dog.woof();
}

Let’s understand what is happening here. In the first, if block, we match animal against the type pattern Cat cat. First, we test the animal variable to see if it’s an instance of Cat. If so, it’ll be cast to our Cat type, and finally, we assign the result to cat.

让我们了解一下这里发生了什么。在第一个if块中,我们将animal与类型模式Cat cat相匹配。首先,我们测试animal变量,看它是否是Cat的一个实例。如果是,它将被转换为我们的Cat 类型,最后,我们将结果赋给cat

It is important to note that the variable name cat is not an existing variable, but instead a declaration of a pattern variable.

需要注意的是,变量名称cat不是一个现有的变量,而是一个模式变量的声明。

We should also mention that the variables cat and dog are only in scope and assigned when the respective pattern match expressions return true. Consequently, if we try to use either variable in another location, the code will generate compiler errors.

我们还应该提到,变量catdog只有在各自的模式匹配表达式返回true时才在范围内并被分配。因此,如果我们试图在其他地方使用这两个变量,代码将产生编译器错误。

As we can see, this version of the code is much easier to understand. We have simplified the code to reduce the overall number of explicit casts dramatically, and the readability is greatly improved.

我们可以看到,这个版本的代码更加容易理解。我们简化了代码,大大减少了显式转换的总体数量,可读性大大增强。

Moreover, this kind of type of test pattern can be particularly useful when writing equality methods.

此外,这种类型的测试模式在编写equality方法时可能特别有用。

4. Conclusion

4.结论

In this short tutorial, we looked at Pattern Matching with instanceof in Java 14. Using this new built-in language enhancement helps us to write better and more readable code, which is generally a good thing.

在这个简短的教程中,我们研究了Java 14中使用instanceof的模式匹配。使用这种新的内置语言增强功能有助于我们写出更好、更可读的代码,这通常是一件好事。

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

一如既往,文章的完整源代码可在GitHub上获得