【问题标题】:Java 8 Optional. Why of and ofNullable?Java 8 可选。为什么of和ofNullable?
【发布时间】:2019-05-17 12:20:53
【问题描述】:

我有一个关于 Java 8 的 Optional 的问题,其目的是解决 NullPointerException 异常。

问题是,让我们选择两种类型的原因是什么:

Optional.of(T value)     <-----non-null value, null value will throw NPE
Optional.ofNullable(T value)   <----- nullable value

因为我期望的是,当我使用时:

Optional.of(nullValue);

它不会抛出NullPointerException


在一些回复后扩展了我的问题:

为什么人们会选择 Optional 而不是普通的 if-else 进行空值检查?

【问题讨论】:

  • 您可能希望返回一个用 Optional 包装的值。在这种情况下,您可以使用Optional.of(value);
  • 人们提供的三个答案中有两个称为 NullPointer。这个问题有多合适....
  • 因为正如其他人在回答中所说,Optional 旨在减少 方法调用者 级别的 NPE,不一定是 方法实现 级别。 Optional.of 用于当一个 知道不是 null(如果是,则应抛出错误),Optional.empty 用于当一个 知道nullOptional.ofNullable用于当一个人不确定值是否为null时。跨度>
  • 对我来说最大的问题是为什么选择这样命名。我会将.of() 用于可空值,然后将ofNotNull() 用于非空值,因为后者使用较少。
  • @JollyJoker 在(Optional 返回)方法的逻辑认为结果已找到但不是或不应该是null 的情况下。一个示例是通过返回Optional.of(matchedItem) 找到匹配项时“短路”循环。如果未找到匹配项,则循环将完成并且该方法将返回 Optional.empty。但是,在某些情况下(可能更频繁,也可能不是),即使方法也无法知道结果是否为null,并且在返回时必须使用Optional.ofNullable

标签: java java-8 optional


【解决方案1】:

Optional.of 的 javadoc 明确读取:

@throws NullPointerException if value is null

这就是使用Optional.ofNullable 来处理您所期望的案件的要求,这是一小段代码:

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value); // 'Optional.of'
}

也就是说,选择一个而不是另一个的决定仍然取决于应用程序设计,好像您的value 可能是null 或不是


在您的期望部分,这不是 Optional 的实际用途。 API 说明进一步澄清了这一点(格式化我的):

Optional 主要用作方法返回类型,其中 明确需要表示“没有结果”,以及在哪里使用 null 可能会导致错误。 类型为Optional 的变量不应该本身就是null;它应该始终指向 Optional 实例。


Optional 的目的是处理 NullPointerException 异常。

旁白:只是为了清楚地指出,该选择当然会隐含地让您定义是否应在运行时抛出 NPE。但在编译时并没有确定。

【讨论】:

    【解决方案2】:

    我认为使用 Javadoc 非常简单明了:

    Optional.of(T value) 用于当您确定不存在 null 值并且出现空值而不是程序抛出 NullPointerException 并视为错误时。

    Optional.ofNullable(T value) 在您知道可能存在 null 值并且在这种情况下您的程序应该正常运行时使用。


    Why would people opt for Optional instead of normal if-else method for null checking?

    【讨论】:

      【解决方案3】:

      Optional 的目的是处理NullPointerException 异常

      是的,但在使用时不是在创建时。

      因此,当您从方法中收到 Optional 时,您可以使用 Optional.ifPresentOptional.orElseOptional.orElseGetOptional.orElseThrow 方法来避免 NPE。

      但是,当您创建 Optional 时,情况并非如此。由于它是您自己的方法,因此您必须知道该对象是否可以为空。


      可选的主要目的是为函数提供一种返回值的方法,以指示没有返回值。见this discussion。这允许调用者继续一系列流畅的方法调用。

      斯图尔特马克

      请阅读this post以获得更详细的解释。

      【讨论】:

        【解决方案4】:

        为什么人们会选择 Optional 而不是普通的 if-else 方法来检查空值?

        Optional&lt;T&gt; 类的主要目的是提供一种方法来执行 null 安全 映射操作。

        employeeOptional.map(Employee::getName).map(String::toUpperCase).ifPresent(upperCasedNameConsumer)

        上面的表达式可以替换单个可读表达式中的级联if-else 语句。

        Optional.of 为给定参数提供了一个断言为 null-null 值,否则,如果您不确定输入,则可以选择 Optional.ofNullable

        我强烈建议您阅读 javadoc for Optional&lt;T&gt; 类,了解更多可选的链接方法,您可以利用这些方法来发挥自己的优势。

        【讨论】:

          【解决方案5】:

          在阅读了一些答案和 cmets 后,我认为缺少此解释。考虑一个类似的方法

          public Optional<String> name(Customer c) {
              return c.isNew() ? Optional.ofNullable(getName(c)) : Optional.of(getName(c));
          }
          

          如果客户不是新客户并且应该有名字,您想在这里抛出NullPointerException;如果是null,您的代码就会不一致。但是,如果客户是新客户,则该名称可能还不存在,因此在这种情况下为 ofNullable,并且该方法返回 Optional

          【讨论】:

            【解决方案6】:
            • Optional.ofNullable 是现有 API 的包装器,可以返回 null。您可以将其称为 API 的使用者。
            • Optional.of/Optional.empty 是针对以Optional 编写的新代码。您将返回使用 of/empty 创建的 Optional 作为 API 的提供者。

            【讨论】:

              【解决方案7】:

              代码示例: Optional.of() VS Optional.ofNullable()

              @Test
              public void TestOptional() {
              
                  String message = "Hello World!";
                  System.out.println("message -> " + message + "\n");
              
                  Optional<String> genderOptional = Optional.of(message);
                  System.out.println("Optional.of(message) -> " + genderOptional);
                  System.out.println("Optional.of(message).get() -> " + genderOptional.get());
                  try {
                      Optional.of(null);
                  } catch (java.lang.NullPointerException e) {
                      System.out.println("Optional.of(null) -> java.lang.NullPointerException \n");
                  }
              
                  System.out.println("Optional.empty() -> " + Optional.empty() + "\n");
              
                  System.out.println("Optional.ofNullable(null) -> " + Optional.ofNullable(null));
                  System.out.println("Optional.ofNullable(message) -> " + Optional.ofNullable(message));
                  System.out.println("Optional.ofNullable(message).get() -> " + Optional.ofNullable(message).get());
              
              }
              

              输出:

              message -> Hello World!
              
              Optional.of(message) -> Optional[Hello World!]
              Optional.of(message).get() -> Hello World!
              Optional.of(null) -> java.lang.NullPointerException 
              
              Optional.empty() -> Optional.empty
              
              Optional.ofNullable(null) -> Optional.empty
              Optional.ofNullable(message) -> Optional[Hello World!]
              Optional.ofNullable(message).get() -> Hello World!
              

              【讨论】:

                【解决方案8】:

                我认为主要目的是 使用Optional.of() 可以抛出空指针 这正是我们在某些情况下所需要的。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-04-29
                  • 2014-04-28
                  相关资源
                  最近更新 更多