java.lang.NullPointerException,只要敢自稱Java程序員,那對這個異常就再熟悉不過了。為了防止拋出這個異常,我們經常會寫出這樣的代碼:
Person person = people.find("John Smith");
if (person != null) {
person.doSomething();
}
在Java世界里,解決空引用問題常見的一種辦法是,使用Null Object模式。這樣的話,在“沒有什么”的情況下,就返回Null Object,客戶端代碼就不用判斷是否為空了。但是,這種做法也有一些問題。首先,我們肯定要為Null Object編寫代碼,而且,如果我們想大規模應用這個模式,我們要為幾乎每個類編寫Null Object。
幸好,我們還有另外一種選擇:Optional。Optional是對可以為空的對象進行的封裝,它實現起來並不復雜。在某些語言里,比如 Scala,Optional實現成了語言的一部分。而對於Java程序員而言,Guava為我們提供了Optional的支持。閑言少敘,先來如何使用 Optional,完成前面的那段代碼
Optional person = people.find("John Smith");
if (person.isPresent()) {
person.get().doSomething();
}
這里如果isPresent()返回false,說明這是個空對象,否則,我們就可以把其中的內容取出來做自己想做的操作了。
如果你期待的是代碼量的減少,恐怕這里要讓你失望了。單從代碼量上來說,Optional甚至比原來的代碼還多。但好處在於,你絕對不會忘記判空,因為這里我們得到的不是Person類的對象,而是Optional。
看完了客戶端代碼,我們再來看看怎樣創建一個Optional對象,基本的規則很簡單:
如果我們知道自己要封裝的對象是一個空對象,可以用
Optional.absent();
如果封裝的對象是一個非空對象,則可以用
Optional.of(obj);
如果不知道對象是否為空,就這樣創建創建
Optional.fromNullable(obj);
有時候,當一個對象為null的時候,我們並不是簡單的忽略,而是給出一個缺省值,比如找不到這個人,任務就交給經理來做。使用Optional可以很容易地做到這一點,以上面的代碼為例:
Optional person = people.find("John Smith");
person.or(manager).doSomething()
說白了,Optinal是給了我們一個更有意義的“空”。
簡單使用實例:
Student student = new Student(); String name = student.getName(); Optional<String> optional = Optional.fromNullable(name); if (optional.isPresent()) { System.out.println("name : " + name); }else { System.out.println("null ........"); student.setName("sungang"); } name = student.getName(); optional = Optional.fromNullable(name); if (optional.isPresent()) { System.out.println("name : " + name); }else { System.out.println("null ........"); student.setName("sungang"); }
結果:
null ........ name : sungang
