Guava的Optional:java
大多数状况下程序员使用null是为了表示某种不存在的意思,也许应该有一个value,可是这个value是空或者这个value找不到。比方说,在用不存在的key值从map中取 value,Map.get返回null表示没有该map中不包含这个key。 程序员
若T类型数据能够为null,Optional<T>是用来以非空值替代T数据类型的一种方法。一个Optional对象能够包含一个非空的T引用(这种状况下咱们称之为“存在的”)或者不包含任何东西(这种状况下咱们称之为“空缺的”)。但Optional历来不会包含对null值的引用。工具
import com.google.common.base.Optional; public class OptionalTest { public void testOptional() throws Exception { Optional<Integer> possible=Optional.of(6); if(possible.isPresent()){ System.out.println("possible isPresent:"+possible.isPresent()); System.out.println("possible value:"+possible.get()); } } }
因为这些缘由,Guava库设计了Optional来解决null的问题。许多Guava的工具被设计成若是有null值存在即刻报错而不是只要上下文接受处理null值就默认使用null值继续运行。并且,Guava提供了Optional等一些工具让你在不得不使用null值的时候,能够更加简便的使用null并帮助你避免直接使用null。
Optional<T>的最经常使用价值在于,例如,假设一个方法返回某一个数据类型,调用这个方法的代码来根据这个方法的返回值来作下一步的动做,若该方法能够返回一个null值表示成功,或者表示失败,在这里看来都是意义含糊的,因此使用Optional<T>做为返回值,则后续代码能够经过isPresent()来判断是否返回了指望的值(本来指望返回null或者返回不为null,其意义不清晰),而且可使用get()来得到实际的返回值。google
Optional方法说明和使用实例:spa
1.经常使用静态方法:设计
Optional.of(T):得到一个Optional对象,其内部包含了一个非null的T数据类型实例,若T=null,则马上报错。
Optional.absent():得到一个Optional对象,其内部包含了空值
Optional.fromNullable(T):将一个T的实例转换为Optional对象,T的实例能够不为空,也能够为空[Optional.fromNullable(null),和Optional.absent()等价。code
使用实例以下:对象
import com.google.common.base.Optional; public class OptionalTest { @Test public void testOptional() throws Exception { Optional<Integer> possible=Optional.of(6); Optional<Integer> absentOpt=Optional.absent(); Optional<Integer> NullableOpt=Optional.fromNullable(null); Optional<Integer> NoNullableOpt=Optional.fromNullable(10); if(possible.isPresent()){ System.out.println("possible isPresent:"+possible.isPresent()); System.out.println("possible value:"+possible.get()); } if(absentOpt.isPresent()){ System.out.println("absentOpt isPresent:"+absentOpt.isPresent()); ; } if(NullableOpt.isPresent()){ System.out.println("fromNullableOpt isPresent:"+NullableOpt.isPresent()); ; } if(NoNullableOpt.isPresent()){ System.out.println("NoNullableOpt isPresent:"+NoNullableOpt.isPresent()); ; } } }
2.实例方法:blog
1>. boolean isPresent():若是Optional包含的T实例不为null,则返回true;若T实例为null,返回false
2>. T get():返回Optional包含的T实例,该T实例必须不为空;不然,对包含null的Optional实例调用get()会抛出一个IllegalStateException异常
3>. T or(T):若Optional实例中包含了传入的T的相同实例,返回Optional包含的该T实例,不然返回输入的T实例做为默认值
4>. T orNull():返回Optional实例中包含的非空T实例,若是Optional中包含的是空值,返回null,逆操做是fromNullable()
5>. Set<T> asSet():返回一个不可修改的Set,该Set中包含Optional实例中包含的全部非空存在的T实例,且在该Set中,每一个T实例都是单态,若是Optional中没有非空存在的T实例,返回的将是一个空的不可修改的Set。
使用实例以下:
get
import java.util.Set; import com.google.common.base.Optional; public class OptionalTest { public void testMethodReturn() { Optional<Long> value = method(); if(value.isPresent()==true){ System.out.println("得到返回值: " + value.get()); }else{ System.out.println("得到返回值: " + value.or(-12L)); } System.out.println("得到返回值 orNull: " + value.orNull()); Optional<Long> valueNoNull = methodNoNull(); if(valueNoNull.isPresent()==true){ Set<Long> set=valueNoNull.asSet(); System.out.println("得到返回值 set 的 size : " + set.size()); System.out.println("得到返回值: " + valueNoNull.get()); }else{ System.out.println("得到返回值: " + valueNoNull.or(-12L)); } System.out.println("得到返回值 orNull: " + valueNoNull.orNull()); } private Optional<Long> method() { return Optional.fromNullable(null); } private Optional<Long> methodNoNull() { return Optional.fromNullable(15L); } }
输出结果:
得到返回值: -12 得到返回值 orNull: null 得到返回值 set 的 size : 1 得到返回值: 15 得到返回值 orNull: 15
Optional除了给null值命名所带来的代码可阅读性的提升,最大的好处莫过于Optional是傻瓜式的。Optional对象的使用强迫你去积极的思考这样一种状况,若是你想让你的程序返回null值,这null值表明的含义是什么,由于你想要取得返回值,必然从Optional对象内部去得到,因此你必然会这么去思考。可是只是简单的使用一个Null值会很轻易的让人忘记去思索代码所要表达的含义究竟是什么,尽管FindBugs有些帮助,可是咱们仍是认为它并无尽量的解决好帮助程序员去思索null值表明的含义这个问题。 这种思考会在你返回某些存在的值或者不存在的值的时候显得特别相关。和其余人同样,你绝对极可能会忘记别人写的方法method(a,b)可能会返回一个null值,就好像当你去写method(a,b)的实现时,你也极可能忘记输入参数a也能够是null。若是返回的是Optional对象,对于调用者来讲,就能够忘却怎么去度量null表明的是什么含义,由于他们始终要从optional对象中去得到真正的返回值。