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對象中去得到真正的返回值。