6个Java不容错过的新特性 -- The Optional Class & The Record class

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

2018年,随着新的发布节奏的采用,Java悄然经历了其发展中最大的变化之一。这个大胆的新计划使Java开发人员每六个月就能得到一个新的功能版本。

这对于保持Java的新鲜感和相关性来说是非常好的,但这也使得它很容易错过功能的引入。这篇文章总结了几个有用的新特性,并对它们进行了概述。

The Optional Class

空指针异常是所有错误中最经典的一种。虽然它可能很熟悉,但它是一个需要防范的非常冗长的问题。至少在Java 8引入(和Java 10完善)Optional类之前是这样。

从本质上讲,Optional类允许你包装一个变量,然后使用包装器的方法来更简洁地处理空值问题。

下面有一个空指针错误的例子,其中一个类的引用foo是空的,一个方法foo.getName()被访问。

public class MyClass {
    public static void main(String args[]) {
      InnerClass foo = null;
      System.out.println("foo = " + foo.getName());
    }
}
class InnerClass {
  String name = "";
  public String getName(){
      return this.name;
  }
}
复制代码

根据你的需要,Optional提供了一些处理这种情况的方法。它有一个isPresent()方法,你可以用它来做一个if-check。然而,这最终是相当冗长的。但是Optional也有功能处理的方法。

例如,下面的代码显示了你如何使用ifPresent()--注意与isPresent()有一个字母的区别--只在有值存在的情况下运行输出代码。

import java.util.Optional;
public class MyClass {
    public static void main(String args[]) {
      InnerClass foo = null; //new InnerClass("Test");
      Optional fooWrapper = Optional.ofNullable(foo);
      fooWrapper.ifPresent(x -> System.out.println("foo = " + x.getName()));
      //System.out.println("foo = " + fooWrapper.orElseThrow());
    }
}
class InnerClass {
  String name = "";
  public InnerClass(String name){
      this.name = name;
  }
  public String getName(){
      return this.name;
  }
}
复制代码

提示:当使用Optional时,如果你使用orElse()方法通过方法调用提供一个默认值,考虑使用orElseGet()来代替提供一个函数引用,以获得性能上的好处,如果值是非空的,就不会运行调用。

The Record Class

构建Java应用的一个常见需求是所谓的不可变的DTO(数据传输对象)。DTOs用于对来自数据库、文件系统和其他数据存储的数据进行建模。传统上,DTOs是通过制作一个类来创建的,其成员通过构造函数来设置,没有访问它们的getters。Java 14引入了新的记录关键字,Java 15在此基础上进行了改进,为这一目的提供了一种速记方式。

下面的例子说明了一个典型的DTO定义和record类型引入前的用法。

public class MyClass {
    public static void main(String args[]) {
      Pet myPet = new Pet("Sheba", 10);

      System.out.println(String.format("My pet %s is aged %s", myPet.getName(), myPet.getAge()));
    }
}
class Pet {
    String name;
    Integer age;
    public Pet(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public Integer getAge(){
        return this.age;
    }
}
复制代码

如下面的例子所示,我们可以使用record关键字来消除大部分的模板。

public class MyClass {
    public static void main(String args[]) {
      Pet myPet = new Pet("Sheba", 10);

      System.out.println(String.format("My pet %s is aged %s", myPet.getName(), myPet.getAge()));
    }
}

public record Pet(String name, Integer age) {}
复制代码

请注意,使用数据对象的客户端代码并没有改变;它的行为就像传统定义的对象一样。record关键字足够聪明,可以通过简单的定义足迹推断出存在哪些字段。

record类型还定义了equals()、hashCode()和toString()的默认实现,同时也允许开发者重写这些。 你也可以提供一个自定义的构造函数。

请注意,record不能被子类化。

感谢观看,这是6个Java不容错过的新特性第1篇文章,如果您有兴趣,可以关注一下我,方便查看后续文章,一起学习,共同进步,不胜感激!

Guess you like

Origin juejin.im/post/7034319830400368677