如何使字段可选?

How to make a field optional?

我有一个class像这样

class User {
  private String firstName;
  private String lastName;

  ...
}

我希望lastName 属性 可选。我如何在 Java 中完成此操作?

在某些语言中,它非常优雅和简单,我们只需在字段名称后附加一个 问号

当你调用它的时候,给它赋值null。 您也可以只为它分配一个空字符串,然后如果您的用例需要,可以使用一种方法来检查它是否为空,并且从那里知道该特定用户只有名字 user("John","")

您可以使用 Optional monad。老实说,我只是保持原样的值,并处理它们在其他地方可以为空的事实(视情况而定):

Optional.ofNullable(user.getFirstName()).orElse("unknown");

Optional.ofNullable(user.getFirstName()).orElseThrow(() 
    -> new InvalidArgumentException("First name is required);

也许只是创建一个 getter returns Optional:

class User {
  private String firstName;
  private String lastName;

  public String getFirstName() {
    return firstName;
  }

  public Optional<String> getLastName() {
    return Optional.ofNullable(lastName);
  }
}

然后:

User user = new User();
...
String lastName = user.getFirstName();
Optional<String> lastName = user.getLastName();

概述

在Java中没有语言概念

在Java中,所有(非原始)类型都是nullable,因此可以看出可选。因此,您可以将其分配 null 并收工。

为了克服与此相关的问题,使意图更清晰并争取 快速失败 ,我看到经常使用的是分配 null在内部和 return Optional<String> 将 return 它的方法上,例如 getLastName() 方法。


代码示例

所以这样做的一种方法可能是:

class User {
  private String firstName;
  private String lastName;

  User(@NotNull String firstName) {
     this(firstName, null);
  }

  User(@NotNull String firstName, @Nullable String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @NotNull Optional<String> getLastName() {
    return Optional.ofNullable(lastName);
  }

  void setLastName(@Nullable String lastName) {
    this.lastName = lastName;
  }

  ...
}

我特意使用了 @NotNull@Nullable 注释,让您更清楚地了解在这样的设计中可以允许 null 的地方。

请注意,如果您有更多可选参数,构建器模式 也可能会派上用场。

最后,首先还要考虑一下具有可选值是否是一个好的设计 - 也许您可以 重新设计 整个事情,从更大的角度来避免这种情况.


可选字段或参数

请注意,通常不建议将字段存储为Optional<String>,也不采用这样的参数,例如setLastName(Optional<String>)

Optional 被设计为仅供那些不想指示缺少 return 值的方法使用。

您可以在此处阅读更多相关信息:

  • Uses for Optional