Java 8可选。为什么of和of为空?

时间:2018-12-17 06:38:58

标签: java java-8 optional

我对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进行null检查?

8 个答案:

答案 0 :(得分:19)

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 < / strong>。


就您的期望而言,这并不是Optional的真正目的。 API注释进一步阐明了这一点(格式化我的格式):

  

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


  

“可选”的目的是解决NullPointerException异常。

旁边:只是为了清楚地指出,选择当然会隐式地让您定义是否应在运行时抛出NPE。它不是在编译时确定的。

答案 1 :(得分:12)

  

可选的目的是解决NullPointerException异常

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

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

但是在创建Optional时并非如此。由于这是您自己的方法,因此您必须知道对象是否可为空。


  

可选的要点是为函数提供一种返回值的手段,以指示缺少返回值。参见this discussion。这样,调用方就可以继续进行一系列流畅的方法调用。

     

斯图尔特标记

有关详细说明,请阅读this post

答案 2 :(得分:6)

我认为Javadoc非常简单明了:

Optional.of(T value) 用于以下情况:确定没有null值并且万一出现空值而不是程序抛出NullPointerException并认为是bug时使用。

Optional.ofNullable(T value) 用于当您知道可以有一个null值并且在这种情况下您的程序应该可以正常运行。


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

答案 3 :(得分:5)

在阅读了一些答案和评论后,我认为缺少这种解释。考虑类似

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

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

答案 4 :(得分:4)

  

为什么人们会选择Optional而不是常规的if-else方法进行null检查?

Optional<T>类的主要目的是为执行空安全映射操作提供一种手段。

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

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

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

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

答案 5 :(得分:1)

  • ValueError: Can only compare identically-labeled Series objects是可返回Optional.ofNullable的现有API的包装。您可以将其称为API的使用者。
  • null用于编写Optional.of/Optional.empty的新代码。您将返回使用Optional创建的Optional作为API的提供者。

答案 6 :(得分:0)

代码示例: 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!

答案 7 :(得分:0)

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