Java8新特性系列-Optional有什么意义?

By | 2022年2月9日

Java 8 Optional

Java 8 中有一个称为 Optional 类的新功能,它应该可以解决 NullPointerExceptions。 显然,这些让开发人员感到恼火的程度比我想象的要多。 很明显,一个对象实际上只是一个指针,而指针可以指向任何东西。 也许不再是了? 也许本世纪大多数计算机科学专业的毕业生从未真正了解过指针,因为学校已经被高级编程语言所吸引。 在这一点上我并不批评,这就像问 90 年代计算机科学专业的学生为什么他们不知道 COBOL。

这个新的 Optional 类的亮点当然是“类”这个词。 Optional 只是一个包装器,它包含对其他对象的引用,并且不是 NullPointerExceptions 的灵丹妙药。

让我们从创建一个生成 NullPointerException 的非常简单的示例开始:

import java.util.Optional;

public class OptionalTest{

  public String getNullString(){
    return (null);
  }

  public Optional<String> getOptionalNullString(){
    return (null);
  }

  public static void main(String[] args){
    OptionalTest optionalTest=new OptionalTest();
    String nullString=optionalTest.getNullString();

    try{
      System.out.println(nullString.toString());
    }catch(NullPointerException x){
      System.out.println("Oh the humanity, a NullPointerException!");
    }
  }
}

是的,toString() 是多余的,但它保证了 NullPointerException,这是我们试图演示的。 所以这是这个问题的可怕老派解决方案:

if(nullString!=null){
  System.out.println(nullString.toString());
}else{
  System.out.println("nullString is null, man that check was a lot of work");
}

所以这里是可选的救援; 除了 Optional 是一个对象,因此它也可以为空:

Optional<String> optionalString=optionalTest.getOptionalNullString();
try{
  if(optionalString.isPresent()){
    System.out.println(optionalString.get().toString());
  }
}catch(NullPointerException x){
  System.out.println("Optional object can be null, sorry dude.");
}

好的,所以这可能不是该类的预期用途。 您应该使用像 Optional.of 这样的静态方法来创建实例。 如果传递了一个空值,这将抛出一个,你猜对了,NullPointerException。 因此,如果目标是避免 NullPointerExceptions,那么这种特定方法仅在您已经知道要分配非空值的情况下才有用,在这种情况下,为什么还需要 Optional? 例子:

try{
  optionalString=Optional.of(optionalTest.getNullString());
  if(optionalString.isPresent()){
    System.out.println(optionalString.get().toString());
  }
}catch(NullPointerException x){
  System.out.println("NullPointerException, I thought Optional totally banished these?!");
}

因此,我们使用 Optional.ofNullable 来创建一个可能包含空值的 Optional 实例。 我们可以在 Optional 上调用 ifPresent 方法,而不是检查空引用的可怕负担:

optionalString=Optional.ofNullable(optionalTest.getNullString());
optionalString.ifPresent(s->{System.out.println(s.toString());});

我真的很困惑为什么这比这更可取:

String s=optionalTest.getNullString();
if(s!=null){System.out.println(s.toString());}

这个新的 Optional 类还有另外两个缺点:

1) 这是使堆管理和调试堆栈跟踪变得更糟的好方法。 同样,Optional 是一个包装器,这意味着如果您使用它,您现在将拥有两个以前拥有的对象引用。

2)它不是可序列化的,因此在许多情况下都无用。

所以回顾一下 - 为了摆脱 NullPointerExceptions 我们有一个新类:

  • 抛出 NullPointerExceptions
  • 本身可以为空,导致 NullPointerException
  • 增加堆大小
  • 使调试更加困难
  • 使序列化对象(例如外部客户端的 XML 或 JSON)变得更加困难

剩下的就是“有什么意义?如果有人对这快有更好的理解,欢迎邮件交流

One thought on “Java8新特性系列-Optional有什么意义?

  1. Pingback: Java8新特性系列-Optional有什么意义?(解答) – 微爱博客

Comments are closed.