"Null 很糟糕." - Doug Lea。不好 Doug Lea 是推荐一位美国的计算机科学家,他是使用 Java 平台的并发和集合框架的主要设计者之一。他在 2014 年的不好一篇文章中说过:“Null sucks.”1,意思是推荐 null 很糟糕。他认为 null 是使用一种不明确的表示,它既可以表示一个值不存在,不好也可以表示一个值未知,推荐也可以表示一个值无效。使用这样就会导致很多逻辑错误和空指针异常,不好给程序员带来很多麻烦。推荐他建议使用 Optional 类来封装可能为空的使用值,从而提高代码的不好可读性和健壮性。 "发明 null 引用是推荐我的十亿美元错误。" - Sir C. A. R. Hoare。使用 Sir C. A. R. Hoare 是一位英国的计算机科学家,他是快速排序算法、Hoare 逻辑和通信顺序进程等重要概念的亿华云计算发明者。他在 2009 年的一个软件会议上道歉说:“I call it my billion-dollar mistake. It was the invention of the null reference in 1965.”,意思是他把 null 引用称为他的十亿美元错误。他说他在 1965 年设计 ALGOL W 语言时,引入了 null 引用的概念,用来表示一个对象变量没有指向任何对象。他当时认为这是一个很简单和自然的想法,但后来发现这是一个非常糟糕的设计,因为它导致了无数的错误、漏洞和系统崩溃。他说他应该使用一个特殊的对象来表示空值,而不是使用 null。 自作者从事 Java 编程一来,就与 null 引用相伴,与 NullPointerException 相遇已经是家常便饭了。 null 引用是一种表示一个对象变量没有指向任何对象的方式,它是 Java 语言中的一个特殊值,服务器租用也是导致空指针异常(NullPointerException)的主要原因。虽然 null 引用可以用来表示一个值不存在或未知,也可以用来节省内存空间。但是它也不符合面向对象的思想,因为它不是一个对象,不能调用任何方法或属性。 可以看到,null 引用并不好,我们应该尽量避免使用 null,那么我们该怎么避免 null 引用引起的逻辑错误和运行时异常嘞? 其实这个问题 Java 的设计者也知道,于是他们在 Java8 之后设计引入了 Optional 类解决这个问题,本文将给大家详细介绍下 Optional 类的设计目的以及使用方法。 Optional 类是 java 8 中引入的一个新的类,它的作用是封装一个可能为空的值,从而避免空指针异常(NullPointerException)。Optional 类可以看作是服务器托管一个容器,它可以包含一个非空的值,也可以为空。Optional 类提供了一些方法,让我们可以更方便地处理可能为空的值,而不需要显式地进行空值检查或者使用 null。 Optional 类的设计是基于函数式编程的思想,它借鉴了 Scala 和 Haskell 等语言中的 Option 类型。Optional 类实现了 java.util.function 包中的 Supplier、Consumer、Predicate、Function 等接口,这使得它可以和 lambda 表达式或者方法引用一起使用,形成更简洁和优雅的代码。 Optional 类是一个不可变的类,它有两个子类:Optional.empty 和 Optional.of。Optional.empty 表示一个空的 Optional 对象,它不包含任何值。Optional.of 表示一个非空的 Optional 对象,它包含一个非空的值。我们可以使用这两个静态方法来创建 Optional 对象。例如: Optional ); 注意,如果我们使用 Optional.of 方法传入一个 null 值,会抛出 NullPointerException。如果我们不确定一个值是否为空,可以使用 Optional.ofNullable 方法,它会根据值是否为空,返回一个相应的 Optional 对象。例如: Optional Optional 类提供了一些方法,让我们可以更方便地处理可能为空的值,而不需要显式地进行空值检查或者使用 null。以下是一些常用的方法: isPresent():判断 Optional 对象是否包含一个非空的值,返回一个布尔值。get():如果 Optional 对象包含一个非空的值,返回该值,否则抛出 NoSuchElementException 异常。 ); (name.isPresent()) { + name.get()); { ); } ); name.ifPresent(s -> { + name.get()); }); ); ); System.out.println(greeting); ); ); System.out.println(greeting); ); )); ); + name.map(s -> s.toUpperCase()).get(); System.out.println(greeting); ); + s)).get(); System.out.println(greeting); ); + name.filter(s -> !s.isEmpty()).get(); System.out.println(greeting); Java 9 中 Optional 类有了一些改进,主要是增加了三个新的方法,分别是 stream()、ifPresentOrElse() 和 or()。这些方法可以让我们更方便地处理可能为空的值,以及和流或其他返回 Optional 的方法结合使用。我来详细讲解一下这些方法的作用和用法。 stream():这个方法可以将一个 Optional 对象转换为一个 Stream 对象,如果 Optional 对象包含一个非空的值,那么返回的 Stream 对象就包含这个值,否则返回一个空的 Stream 对象。这样我们就可以利用 Stream 的各种操作来处理 Optional 的值,而不需要显式地判断是否为空。我们可以用 stream() 方法来过滤一个包含 Optional 的列表,只保留非空的值,如下所示:List Optional.empty(), ), Optional.empty(), ) ); List .flatMap(Optional::stream) .collect(Collectors.toList()); System.out.println(filteredList); ); optional.ifPresentOrElse( + x), ) ); optional = Optional.empty(); optional.ifPresentOrElse( + x), ) ); ); ); optional = optional.or(supplier); optional.ifPresent(x -> System.out.println(x)); optional = Optional.empty(); optional = optional.or(supplier); optional.ifPresent(x -> System.out.println(x)); 总结一下使用 Optional 类的几个好处: 总之,Optional 类是一个非常有用的类,它可以帮助我们更好地处理可能为空的值,提高代码的质量和效率。所以我强烈推荐你在 Java 开发中使用 Optional 类,你会发现它的魅力和好处。 ·END·Optional 类是什么?
Optional 类的设计
Optional 类的使用方法
Java 9 中 Optional 改进
最后