对于一个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
接下来,通过一个例子来看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
为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