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

溫馨提示×

溫馨提示×

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

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

怎么避免在Java代碼中寫大量的判空語句

發布時間:2022-03-01 13:53:54 來源:億速云 閱讀:312 作者:iii 欄目:開發技術

這篇文章主要介紹了怎么避免在Java代碼中寫大量的判空語句的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇怎么避免在Java代碼中寫大量的判空語句文章都會有所收獲,下面我們一起來看看吧。

有人說可以使用 JDK8提供的 Optional 來避免判空,但是用起來還是有些麻煩。

作者在日常工作中,封裝了一個工具,可以鏈式調用對象成員而無需判空,相比原有的if null邏輯 和 JDK8提供的 Optional 更加優雅易用,在工程實踐中大大提高了編碼效率,也讓代碼更加的精準和優雅。

不優雅的判空調用

我想從事 Java 開發的小伙伴肯定有遇到過下面這種讓人難受的判空邏輯:現在有一個User類,School 是它的成員變量

/**


* @author Axin


* @since 2020-09-20


* @summary 一個User類定義


 * (Ps:Data 是lombok組件提供的注解,簡化了get set等等的約定代碼)


*/


@Data


public class User {


    private String name;


    private String gender;


    private School school;


    @Data


    public static class School {


        private String scName;


        private String adress;


    }


}

現在想要獲得School的成員變量 adress , 一般的處理方式:

public static void main(String[] args) {


    User axin = new User();


    User.School school = new User.School();


    axin.setName("hello");


    if (Objects.nonNull(axin) && Objects.nonNull(axin.getSchool())) {


        User.School userSc = axin.getSchool();


        System.out.println(userSc.getAdress());


    }


}

獲取 adress 時要對 School 進行判空,雖然有些麻煩,到也能用,通過 JDK8 提供的 Optional 工具也是可以,但還是有些麻煩。

而下文的 OptionalBean 提供一種可以鏈式不斷地調用成員變量而無需判空的方法,直接鏈式調用到你想要獲取的目標變量,而無需擔心空指針的問題。

鏈式調用成員變量

如果用了本文設計的工具 OptionalBean ,那么上述的調用可以簡化成這樣:

public static void main(String[] args) {


    User axin = new User();


    User.School school = new User.School();


    axin.setName("hello");


    // 1. 基本調用


    String value1 = OptionalBean.ofNullable(axin)


            .getBean(User::getSchool)


            .getBean(User.School::getAdress).get();


    System.out.println(value1);


}

執行結果:

怎么避免在Java代碼中寫大量的判空語句

其中User的school變量為空,可以看到代碼并沒有空指針,而是返回了null。這個工具怎么實現的呢?

OptionalBean 工具

/**


* @author Axin


* @since 2020-09-10


* @summary 鏈式調用 bean 中 value 的方法


*/


public final class OptionalBean<T> {


    private static final OptionalBean<?> EMPTY = new OptionalBean<>();


    private final T value;


    private OptionalBean() {


        this.value = null;


    }


    /**


     * 空值會拋出空指針


     * @param value


     */


    private OptionalBean(T value) {


        this.value = Objects.requireNonNull(value);


    }


    /**


     * 包裝一個不能為空的 bean


     * @param value


     * @param <T>


     * @return


     */


    public static <T> OptionalBean<T> of(T value) {


        return new OptionalBean<>(value);


    }


    /**


     * 包裝一個可能為空的 bean


     * @param value


     * @param <T>


     * @return


     */


    public static <T> OptionalBean<T> ofNullable(T value) {


        return value == null ? empty() : of(value);


    }


    /**


     * 取出具體的值


     * @param fn


     * @param <R>


     * @return


     */


    public T get() {


        return Objects.isNull(value) ? null : value;


    }


    /**


     * 取出一個可能為空的對象


     * @param fn


     * @param <R>


     * @return


     */


    public <R> OptionalBean<R> getBean(Function<? super T, ? extends R> fn) {


        return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value));


    }


    /**


     * 如果目標值為空 獲取一個默認值


     * @param other


     * @return


     */


    public T orElse(T other) {


        return value != null ? value : other;


    }


    /**


     * 如果目標值為空 通過lambda表達式獲取一個值


     * @param other


     * @return


     */


    public T orElseGet(Supplier<? extends T> other) {


        return value != null ? value : other.get();


    }


    /**


     * 如果目標值為空 拋出一個異常


     * @param exceptionSupplier


     * @param <X>


     * @return


     * @throws X


     */


    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {


        if (value != null) {


            return value;


        } else {


            throw exceptionSupplier.get();


        }


    }


    public boolean isPresent() {


        return value != null;


    }


    public void ifPresent(Consumer<? super T> consumer) {


        if (value != null)


            consumer.accept(value);


    }


    @Override


    public int hashCode() {


        return Objects.hashCode(value);


    }


    /**


     * 空值常量


     * @param <T>


     * @return


     */


    public static<T> OptionalBean<T> empty() {


        @SuppressWarnings("unchecked")


        OptionalBean<T> none = (OptionalBean<T>) EMPTY;


        return none;


    }


}

工具設計主要參考了 Optional 的實現,再加上對鏈式調用的擴展就是上述的OptionalBean。

getBean 其實是當變量為空時返回了一個 包裝空值的 OptionalBean 對象,同時泛型的使用讓工具更加易用。

使用手冊

可以看到代碼中也提供了和 Optional 一樣的擴展方法,如 ifPresent()、orElse()等等:

public static void main(String[] args) {


    User axin = new User();


    User.School school = new User.School();


    axin.setName("hello");


    // 1. 基本調用


    String value1 = OptionalBean.ofNullable(axin)


            .getBean(User::getSchool)


            .getBean(User.School::getAdress).get();


    System.out.println(value1);


    // 2. 擴展的 isPresent方法 用法與 Optional 一樣


    boolean present = OptionalBean.ofNullable(axin)


            .getBean(User::getSchool)


            .getBean(User.School::getAdress).isPresent();


    System.out.println(present);


    // 3. 擴展的 ifPresent 方法


    OptionalBean.ofNullable(axin)


            .getBean(User::getSchool)


            .getBean(User.School::getAdress)


            .ifPresent(adress -> System.out.println(String.format("地址存在:%s", adress)));


    // 4. 擴展的 orElse


    String value2 = OptionalBean.ofNullable(axin)


            .getBean(User::getSchool)


            .getBean(User.School::getAdress).orElse("家里蹲");


    System.out.println(value2);


    // 5. 擴展的 orElseThrow


    try {


        String value3 = OptionalBean.ofNullable(axin)


                .getBean(User::getSchool)


                .getBean(User.School::getAdress).orElseThrow(() -> new RuntimeException("空指針了"));


    } catch (Exception e) {


        System.out.println(e.getMessage());


    }


}

關于“怎么避免在Java代碼中寫大量的判空語句”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“怎么避免在Java代碼中寫大量的判空語句”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

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

AI

分宜县| 即墨市| 文安县| 贺兰县| 迁西县| 唐山市| 大关县| 武胜县| 来凤县| 武乡县| 兴海县| 金门县| 彭山县| 嫩江县| 白银市| 泰州市| 乌恰县| 江都市| 漳平市| 祁连县| 康保县| 建瓯市| 磐石市| 郁南县| 怀集县| 治县。| 武夷山市| 宁津县| 盱眙县| 舟山市| 萝北县| 阿鲁科尔沁旗| 临澧县| 奉新县| 道真| 观塘区| 孝昌县| 林口县| 咸阳市| 沁阳市| 都安|