亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java 8 Optional如何優雅地避免NPE

發布時間:2021-09-27 09:33:00 來源:億速云 閱讀:157 作者:柒染 欄目:大數據

這篇文章給大家介紹Java 8 Optional如何優雅地避免NPE,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

空指針異常(NullPointException,簡稱 NPE)可以說是所有 Java 程序員都遇到過的一個異常,雖然 Java 從設計之初就力圖讓程序員脫離指針的苦海,但是指針確實是實際存在的,而 Java 設計者也只能是讓指針在 Java 語言中變得更加簡單易用,而不能完全剔除,所以才有了常見對的關鍵字 null。

避免使用 null 檢查

空指針異常是一個運行時異常,對于這一類異常,如果沒有明確的處理方式,那么最佳實踐在于讓程序早點掛掉。當異常真的發生的時候,處理方式也很簡單,在存在異常的地方添加一個 if 語句判定即可。比如下面的代碼:

public String bindUserToRole(User user) {
    if (user == null) {
        return;
    }

    String roleId = user.getRoleId();
    if (roleId == null) {
        return;
    }

    Role = roleDao.findOne(roleId);
    if (role != null) {
        role.setUserId(user.getUserId());
        roleDao.save(role);
    }
}

但是這樣的應對方式會讓程序出現越來越多的 null 判定,一個良好的程序設計,應該讓代碼中盡量少出現 null 關鍵字,因此 Java 8 引入 Optional 類來避免 NPE 問題,同時也提升了代碼的美觀度。但并不是對 null 關鍵字的一種替代,而是對于 null 判定提供了一種更加優雅的實現,從而避免 NPE 問題。

Optional 類

為了更好的解決和避免常見的 NPE 問題,Java 8 中引入了一個新的類 java.util.Optional<T>,Optional 值可以為 null,如果值存在,調用 isPresent() 方法返回 true,調用 get() 方法可以獲取值。

創建 Optional 對象

Optional 類提供類三個方法用于實例化一個 Optional 對象,它們分別為 empty()、of()、ofNullable(),這三個方法都是靜態方法,可以直接調用。

empty() 方法用于創建一個沒有值的Optional對象:

Optional<String> emptyOpt = Optional.empty();

empty() 方法創建的對象沒有值,如果對 emptyOpt 變量調用 isPresent() 方法會返回 false,調用 get() 方法拋出 NPE 異常。

of() 方法使用一個非空的值創建Optional對象:

String str = "Hello World";
Optional<String> notNullOpt = Optional.of(str);

ofNullable() 方法接收一個可以為null的值:

Optional<String> nullableOpt = Optional.ofNullable(str);

如果 str 的值為 null,得到的 nullableOpt 是一個沒有值的 Optional 對象。

獲取 Optional 對象中的值

如果我們要獲取 User 對象中的 roleId 屬性值,常見的方式是直接獲取:

String roleId = null;
if (user != null) {
    roleId = user.getRoleId();
}

使用 Optional 中提供的 map() 方法可以更簡單地實現:

Optional<User> userOpt = Optional.ofNullable(user);
Optional<String> roleIdOpt = userOpt.map(User::getRoleId);

使用 orElse()方法獲取值

Optional 類還包含其他方法用于獲取值,這些方法分別為:

  • orElse():如果有值就返回,否則返回一個給定的值作為默認值

  • orElseGet():與 orElse() 方法作用類似,區別在于生成默認值的方式不同。該方法接受一個 Supplier<? extends T> 函數式接口參數,用于生成默認值

  • orElseThrow():與前面介紹的 get() 方法類似,當值為 null 時調用這兩個方法都會拋出 NPE 異常,區別在于該方法可以指定拋出的異常類型

下面來看看這三個方法的具體用法:

String str = "Hello World";
Optional<String> strOpt = Optional.of(str);
String orElseResult = strOpt.orElse("Hello BeiJing");
String orElseGet = strOpt.orElseGet(() -> "Hello BeiJing");
String orElseThrow = strOpt.orElseThrow(
        () -> new IllegalArgumentException("Argument 'str' cannot be null or blank."));

此外,Optional 類還提供了一個 ifPresent() 方法,該方法接收一個 Consumer<? super T> 函數式接口,一般用于將信息打印到控制臺:

Optional<String> strOpt = Optional.of("Hello World");
strOpt.ifPresent(System.out::println);

使用 filter() 方法過濾

filter() 方法可用于判斷 Optional 對象是否滿足給定條件,一般用于條件過濾:

Optional<String> optional = Optional.of("wupx94@qq.com");
optional = optional.filter(str -> str.contains("wupx"));

在上面的代碼中,如果 filter() 方法中的 Lambda 表達式成立,filter() 方法會返回當前 Optional 對象值,否則,返回一個值為空的 Optional 對象。

關于 Optional 使用建議:

  • 盡量避免在程序中直接調用 Optional 對象的 get() 和 isPresent() 方法

  • 避免使用 Optional 類型聲明實體類的屬性

Optional 實踐

上面提到創建 Optional 對象有三個方法,empty() 方法比較簡單,主要是 of() 和 ofNullable() 方法。當你確定一個對象不可能為 null 的時候,應該使用 of() 方法,否則,盡可能使用 ofNullable() 方法,比如:

public static void method(Role role) {
    // 當Optional的值通過常量獲得或者通過關鍵字 new 初始化,可以直接使用 of() 方法
    Optional<String> strOpt = Optional.of("Hello World");
    Optional<User> userOpt = Optional.of(new User());

    // 方法參數中role值不確定是否為null,使用 ofNullable() 方法創建
    Optional<Role> roleOpt = Optional.ofNullable(role);
}

orElse() 方法的使用

return str != null ? str : "Hello World"

上面的代碼表示判斷字符串 str 是否為空,不為空就返回,否則,返回一個常量。使用 Optional 類可以表示為:

return strOpt.orElse("Hello World")

簡化 if-else

User user = ...
if (user != null) {
    String userName = user.getUserName();
    if (userName != null) {
        return userName.toUpperCase();
    } else {
        return null;
    }
} else {
    return null;
}

上面的代碼可以簡化成:

User user = ...
Optional<User> userOpt = Optional.ofNullable(user);

return userOpt.map(User::getUserName)
            .map(String::toUpperCase)
            .orElse(null);

注意事項

Optional 是一個 final 類,未實現任何接口,Optional 不能序列化,不能作為類的字段(field),所以當我們在利用該類包裝定義類的屬性的時候,如果我們定義的類有序列化的需求,那么因為 Optional 沒有實現 Serializable 接口,這個時候執行序列化操作就會有問題:

import java.util.Optional;
import lombok.Data;

@Data
public class User implements Serializable {
    private String name;
    private String gender;
    private Optional<String> phone; // 不能序列化
}

可以通過自己實現 getter 方法,使 Lomok 不自動生成,如下:

import java.util.Optional;
import lombok.Data

@Data
public class User implements Serializable  {
    private String name;
    private String gender;
    private String phone;
    public Optional<String> getPhone() {
        return Optional.ofNullable(phone);
    }
}

Java 8 中 Optional 類可以讓我們以函數式編程的方式處理 null 值,拋棄了 Java 8 之前需要嵌套大量 if-else 代碼塊,使代碼可讀性有了很大的提高,但是應盡量避免使用 Optional 類型聲明實體類的屬性。

關于Java 8 Optional如何優雅地避免NPE就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宝兴县| 鄂托克前旗| 广元市| 西城区| 巴林右旗| 南城县| 奎屯市| 丘北县| 铜梁县| 湘潭市| 蛟河市| 沁源县| 弥勒县| 顺义区| 巴塘县| 繁昌县| 吴川市| 鄂温| 衢州市| 长顺县| 吉隆县| 五河县| 上饶县| 济阳县| 桃江县| 乌鲁木齐市| 乡宁县| 神农架林区| 桂林市| 长葛市| 蓬莱市| 鱼台县| 德阳市| 泌阳县| 东丽区| 墨脱县| 德兴市| 晋州市| 平果县| 历史| 彭山县|