Java8使用Optional避免空检查
来源:互联网 发布:社交网络的好处和坏处 编辑:程序博客网 时间:2024/05/20 11:20
Java8使用Optional避免空检查
1. 认识空指针
空指针错误众所周知。Tony Hoare,空指针的发明人在2009年道歉,称之为 数十亿美元的错误。原文如下:
I call it my billion-dollarmistake. It was the invention of the null reference in 1965. At that time, Iwas designing the first comprehensive type system for references in an objectoriented language (ALGOL W). My goal was to ensure that all use of referencesshould be absolutely safe, with checking performed automatically by thecompiler. But I couldn't resist the temptation to put in a null reference,simply because it was so easy to implement. This has led to innumerable errors,vulnerabilities, and system crashes, which have probably caused a billiondollars of pain and damage in the last forty years.
我们如何避免空指针错误,显然的答案是到处使用空检查,因为空检查麻烦且痛苦,很多语言添加了简易的语法实现,如Groovy 和Kotlin。下面是Groovy语法示例。
displayName = user.name ? user.name: 'Anonymous' displayName = user.name ?: 'Anonymous'
2. java8空指针处理
让人失望的是java没有这样的语法,但java8有专门的Optional来实现,示例解释说明。假设我们有下面的类:
class Outer { Nested nested; Nested getNested() { return nested; }}class Nested { Inner inner; Inner getInner() { return inner; }}class Inner { String foo; String getFoo() { returnfoo; }}
使用原来java空检查方式,需要深度嵌套,代码如下:
Outer outer = new Outer();if (outer != null && outer.nested!= null && outer.nested.inner != null) { System.out.println(outer.nested.inner.foo);}
让我们干掉所有的空检查,使用java8Optional类型。map方法输入参数是lambda表达式,自动封装每个函数返回值至Optional,且可以管道式连接多个map操作,null检查自动完成。
Optional.of(new Outer()) .map(Outer::getNested) .map(Nested::getInner) .map(Inner::getFoo).ifPresent(System.out::println);
3. 认识下Optional类
Optional类是一个包装非空对象的容器类型。Optional对象使用缺失值表示null值,其表达的意思即为值有可能为null。意在在java系统中减少空指针异常。看下面示例:
public Optional<Customer>findCustomerWithSSN(String ssn) { ...} Optional<Customer> optional = findCustomerWithSSN(ssn); if (optional.isPresent()) { Customercustomer = maybeCustomer.get(); ... usecustomer ...}else { ...deal with absence case ...}
当然最好还是使用ifPresent。
optional.ifPresent(ssn -> { String s = ssn.toUpperCase(); System.out.println("The longest name is "+ s); }); findCustomerWithSSN(ssn).ifPresent(() -> System.out.println("customerexists!"));
也可以使用orElse。
Long value =findOptionalLong(ssn).orElse(0L);
4. Optional类使用场景
Optional类应该作为可能有返回值函数的返回值类型。有人甚至建议Optional类应该改名为OptionalReturn。
Optional类不是为了避免所有的空指针类型机制。方法或构造函数输入参数强制性检查就仍然是有必要的。
在以下场景一般不建议使用Optional类。
- 领域模型层(非序列化)
- 数据传输对象(同上原因)
- 方法的输入参数
- 构造函数参数
5. Optional类方法参考
下面摘抄Optional类的方法,供参考。
序号
方法和描述
1
static <T> Optional<T> empty()
Returns an empty Optional instance.
2
boolean equals(Object obj)
Indicates whether some other object is "equal to" this Optional.
3
Optional<T> filter(Predicate<? super <T> predicate)
If a value is present and the value matches a given predicate, it returns an Optional describing the value, otherwise returns an empty Optional.
4
<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)
If a value is present, it applies the provided Optional-bearing mapping function to it, returns that result, otherwise returns an empty Optional.
5
T get()
If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.
6
int hashCode()
Returns the hash code value of the present value, if any, or 0 (zero) if no value is present.
7
void ifPresent(Consumer<? super T> consumer)
If a value is present, it invokes the specified consumer with the value, otherwise does nothing.
8
boolean isPresent()
Returns true if there is a value present, otherwise false.
9
<U>Optional<U> map(Function<? super T,? extends U> mapper)
If a value is present, applies the provided mapping function to it, and if the result is non-null, returns an Optional describing the result.
10
static <T> Optional<T> of(T value)
Returns an Optional with the specified present non-null value.
11
static <T> Optional<T> ofNullable(T value)
Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
12
T orElse(T other)
Returns the value if present, otherwise returns other.
13
T orElseGet(Supplier<? extends T> other)
Returns the value if present, otherwise invokes other and returns the result of that invocation.
14
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
Returns the contained value, if present, otherwise throws an exception to be created by the provided supplier.
15
String toString()
Returns a non-empty string representation of this Optional suitable for debugging.
- Java8使用Optional避免空检查
- Java8---Optional避免空指针异常
- Java8之Optional类(避免空指针异常)
- 使用Optional来避免空指针
- Java8 Optional使用
- java8 Optional使用demo
- java8 Optional防止空指针异常初探
- Java8 如何正确使用Optional
- Java8-optional
- java8 Optional
- Java8 Optional
- Java8学习记录--Optional使用范例
- 使用 Java8 Optional 的正确姿势
- 使用 Java8 Optional 的正确姿势
- Java8 中Optional类的使用
- 【Guava】Optional接口来避免空指针错误
- 6.如何正确使用Optional-java8新特性
- Java8中的Optional类
- centeron忘记登陆密码
- freeswitch语音会议在特定应用下降低资源消耗方法
- 系统架构演化历程
- ov5640_mipi.c分析
- 微信小程序-封装了一个画饼的函数
- Java8使用Optional避免空检查
- java-poi-操作excel
- 小项目-星级评分系统
- Projections-Java下MongoDB查询限制返回字段
- DISKGEN 专业版修改硬盘为GPT分区 ESP分区图文教程
- Android Studio升级版本后新建或导入项目,一直卡在building gradle project info
- TextView跑马灯效果
- 逆向还原C语言代码 练习1
- c语言goto语句的使用