Java8 如何正確使用 Optional


	<div class="copyright-area">原文出處: <a ref="nofollow" target="_blank" href="https://blog.kaaass.net/archives/764">kaaass</a></div>

Optional是Java8提供的為了解決null安全問題的一個API。善用Optional可以使我們代碼中很多繁瑣、丑陋的設計變得十分優雅。這篇文章是建立在你對Optional的用法有一定了解的基礎上的,如果你還不太了解Optional,可以先去看看相關教程,或者查閱Java文檔。

使用Optional,我們就可以把下面這樣的代碼進行改寫。

1
2
3
4
5
public static String getName(User u) {
     if (u == null )
         return "Unknown" ;
     return u.name;
}

不過,千萬不要改寫成這副樣子。

1
2
3
4
5
6
public static String getName(User u) {
     Optional<User> user = Optional.ofNullable(u);
     if (!user.isPresent())
         return "Unknown" ;
     return user.get().name;
}

這樣改寫非但不簡潔,而且其操作還是和第一段代碼一樣。無非就是用isPresent方法來替代u==null。這樣的改寫並不是Optional正確的用法,我們再來改寫一次。

1
2
3
4
5
public static String getName(User u) {
     return Optional.ofNullable(u)
                     .map(user->user.name)
                     .orElse( "Unknown" );
}

這樣才是正確使用Optional的姿勢。那么按照這種思路,我們可以安心的進行鏈式調用,而不是一層層判斷了。看一段代碼:

1
2
3
4
5
6
7
8
9
10
11
12
public static String getChampionName(Competition comp) throws IllegalArgumentException {
     if (comp != null ) {
         CompResult result = comp.getResult();
         if (result != null ) {
             User champion = result.getChampion();
             if (champion != null ) {
                 return champion.getName();
             }
         }
     }
     throw new IllegalArgumentException( "The value of param comp isn't available." );
}

由於種種原因(比如:比賽還沒有產生冠軍、方法的非正常調用、某個方法的實現里埋藏的大禮包等等),我們並不能開心的一路comp.getResult().getChampion().getName()到底。而其他語言比如kotlin,就提供了在語法層面的操作符加持:comp?.getResult()?.getChampion()?.getName()。所以講道理在Java里我們怎么辦!

讓我們看看經過Optional加持過后,這些代碼會變成什么樣子。

1
2
3
4
5
6
7
public static String getChampionName(Competition comp) throws IllegalArgumentException {
     return Optional.ofNullable(comp)
             .map(c->c.getResult())
             .map(r->r.getChampion())
             .map(u->u.getName())
             .orElseThrow(()-> new IllegalArgumentException( "The value of param comp isn't available." ));
}

這就很舒服了。Optional給了我們一個真正優雅的Java風格的方法來解決null安全問題。雖然沒有直接提供一個操作符寫起來短,但是代碼看起來依然很爽很舒服。更何況?.這樣的語法好不好看還見仁見智呢。

還有很多不錯的使用姿勢,比如為空則不打印可以這么寫:

1
string.ifPresent(System.out::println);

Optional的魅力還不止於此,Optional還有一些神奇的用法,比如Optional可以用來檢驗參數的合法性。

1
2
3
4
public void setName(String name) throws IllegalArgumentException {
     this .name = Optional.ofNullable(name).filter(User::isNameValid)
                         .orElseThrow(()-> new IllegalArgumentException( "Invalid username." ));
}

這樣寫參數合法性檢測,應該足夠優雅了吧。

參考資料

  • 使用 Java8 Optional 的正確姿勢 – 隔葉黃鶯 Unmi Blog (https://unmi.cc/proper-ways-of-using-java8-optional/)
    <!-- BEGIN #author-bio -->
</div>

原文地址:http://www.importnew.com/26066.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM