天道不一定酬所有勤
但是,天道只酬勤

使用Optional避免NullPointerException

对于一个Java开发人员来说,最常见的异常估计就是NullPointerException了。
当需要一个对象的而程序试图使用null的时候,就会抛出NPE。

粗心的使用null会造成各种惊人的错误。通过研究Google代码库,我们发现95%的集合不应该包含任何null值,让这些情况快速失败,而不是默默地接受null对开发人员来说更有用。

此外,null是不讨人喜欢的,因为他代表着模棱两可。很难去判断返回一个null代表着什么意思。例如,如果Map.get(key)返回一个null。你很难判断是返回的值本身是null,还是值在map中根本不存在。null可以表示成功、失败甚至任何情况。在写代码时我们应该尽量使用其他方式来代替null来明确表达你的意愿。

不得不说,在某些特定场景中使用null也是很正确的。无论在内存方面还是在性能方面,null都有其自身的优势。所以,在对象数组中使用null是不可避免的。但相对于底层库来说,在应用级别的代码中,他确实导致了很多混乱,也带来了很多不确定的语义和不容易解决的bug。就像使用Map.get一样,null代表着多种语义。关键的原因就是,null并无法明确的表示他自身的意义。

当null可以被用来一个不存在的东西时,我们不得不花更多的努力来确保程序不会抛出NullPointerExcepiton,其实常用的方法之一是:

if(user != null){
    user.login();
}

但是,相信很多人都厌倦了这种写法。

Optional

Guava库(Java8中也提供了)中提供了Optional接口来使null快速失败,即在可能为null的对象上做了一层封装。Optional的最常用价值在于,例如,假设一个方法返回某一个数据类型,调用这个方法的代码来根据这个方法的返回值来做下一步的动作,若该方法可以返回一个null值表示成功,或者表示失败,在这里看来都是意义含糊的,所以使用Optional作为返回值,则后续代码可以通过isPresent()来判断是否返回了期望的值(原本期望返回null或者返回不为null,其意义不清晰),并且可以使用get()来获得实际的返回值。

接下来,通过一个例子来看Optional到底有什么用,我们写一个方法,判断当前用户的用户名是为null,如果用户名为null,我们就叫他游客。

code1

public void sayHello(String name){
    if(name==null){
        name = "游客";
    }
    System.out.println("Hello, "+name);
}

code2

import com.google.common.base.Optional;

public void sayHello(String name){
    name = Optional.fromNullable(name).or("游客");
    System.out.println("Hello, "+name);
}

单从代码风格上来看,我们可以看出code2显得更加优雅。

使用Optional除了赋予null语义,增加了可读性,最大的优点在于它是一种傻瓜式的防护。
Guava中Optional类就是用来强制提醒开发者,注意对Null的判断。迫使你积极思考引用缺失的情况

常用方法:

Optional.of(T)
为Optional赋值,当T为Null直接抛NullPointException,建议这个方法在调用的时候直接传常量,不要传变量

Optional.fromNullable(T)

为Optional赋值,当T为Null则使用默认值。建议与or方法一起用,风骚无比

T or(T)

当Optional的值为null时,使用or赋予的值返回。与fromNullable是一对好基友

Optional.absent()

为Optional赋值,采用默认值

T get()

当Optional的值为null时,抛出IllegalStateException,返回Optional的值

boolean isPresent()

如果Optional存在值,则返回True

T orNull()

当Optional的值为null时,则返回Null。否则返回Optional的值

Set asSet()

将Optional中的值转为一个Set返回,当然只有一个值啦,或者为空,当值为null时。

参考资料:

Guava Optional 的应用

Using and avoiding null

拓展阅读

What’s the point of Guava’s Optional class

(全文完)
欢迎关注HollisChuang微信公众账号
打赏

如未加特殊说明,此网站文章均为原创,转载必须注明出处。HollisChuang's Blog » 使用Optional避免NullPointerException

分享到:更多 ()

HollisChuang's Blog

联系我关于我