【问题标题】:How to make a field optional?如何使字段可选?
【发布时间】:2022-01-01 01:18:16
【问题描述】:

我有这样的课

class User {
  private String firstName;
  private String lastName;

  ...
}

我希望lastName 属性为可选。我如何在 Java 中实现这一点?

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

【问题讨论】:

  • Java 中没有这个概念。大多数人只会将null 分配给它,然后在返回它的方法上返回Optional<String>。 (通常不建议将事物存储为Optional<String>,也不接受这样的参数,只返回它)。
  • 你已经实现了。所有引用类型都可以为空。
  • 可选是什么意思?它已经是一种可选的,因为您决定是否为您的属性分配一个值。
  • 在像 Kotlin 这样的语言中,String 是不可为空的,而 String? 是可空的。在 Java 中,所有字符串都可以为空,因此您可以将所有字符串视为可选。现在您的问题应该是:如何使它们成为非可选的。这是一个棘手的问题。

标签: java optional


【解决方案1】:

概述

在 Java 中没有语言概念

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

为了克服与此相关的问题,使意图更清晰并争取快速失败,我看到经常使用的是在内部分配null并返回@987654325 @ 在将返回它的方法上,例如 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

请注意,如果您有更多可选参数,builder-pattern 也可能会派上用场。

最后,首先还要考虑一下具有可选值是否是一个好的设计 - 也许你可以重新设计整个事情在更大的范围内,以避免所有情况。


可选字段或参数

请注意,通常不建议将该字段存储为Optional&lt;String&gt;,也不接受此类参数,例如setLastName(Optional&lt;String&gt;)

Optional 被设计为仅用于希望指示缺少返回值的方法。

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

【讨论】:

    【解决方案2】:

    也许只需创建一个返回 Optional 的 getter:

    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();
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-14
          • 2014-06-09
          • 1970-01-01
          • 2012-06-14
          • 1970-01-01
          • 2020-02-17
          • 2018-06-26
          相关资源
          最近更新 更多