www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > > 程序員小灰
[導(dǎo)讀]對于Java程序員來說,null是令人頭痛的東西。時(shí)常會(huì)受到空指針異常(NPE)的騷擾。連Java的發(fā)明者都承認(rèn)這是他的一項(xiàng)巨大失誤。那么,有什么辦法可以避免在代碼中寫大量的判空語句呢?有人說可以使用JDK8提供的Optional來避免判空,但用起來還是有些麻煩。作者在日常工作中封裝了一個(gè)工具,可以鏈?zhǔn)秸{(diào)用對象成員而無需判空,相比原有的if null邏輯和JDK8提供的Optional更加優(yōu)雅易用。

△Hollis, 一個(gè)對Coding有著獨(dú)特追求的人△ 這是Hollis的第 307 篇原創(chuàng)分享 作者 l  上帝愛吃蘋果 來源 l Hollis(ID:hollischuang)

對于Java程序員來說,null是令人頭痛的東西。時(shí)常會(huì)受到空指針異常(NPE)的騷擾。連Java的發(fā)明者都承認(rèn)這是他的一項(xiàng)巨大失誤。 那么,有什么辦法可以避免在代碼中寫大量的判空語句呢? 有人說可以使用 JDK8提供的 Optional 來避免判空,但是用起來還是有些麻煩。 作者在日常工作中,封裝了一個(gè)工具,可以可以鏈?zhǔn)秸{(diào)用對象成員而無需判空,相比原有的if null邏輯 和 JDK8提供的 Optional 更加優(yōu)雅易用,在工程實(shí)踐中大大提高了編碼效率,也讓代碼更加的精準(zhǔn)和優(yōu)雅。

不優(yōu)雅的判空調(diào)用 我想從事Java開發(fā)的小伙伴肯定有遇到過下面這種讓人難受的判空邏輯:現(xiàn)在有一個(gè)User類,School 是它的成員變量

/**

@author Axin

@since 2020-09-20

@summary 一個(gè)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;

    }

}

現(xiàn)在想要獲得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時(shí)要對School進(jìn)行判空,雖然有些麻煩,到也能用,通過 JDK8 提供的 Optional 工具也是可以,但還是有些麻煩。 而下文的 OptionalBean 提供一種可以鏈?zhǔn)讲粩嗟卣{(diào)用成員變量而無需判空的方法,直接鏈?zhǔn)秸{(diào)用到你想要獲取的目標(biāo)變量,而無需擔(dān)心空指針的問題。

鏈?zhǔn)秸{(diào)用成員變量 如果用了本文設(shè)計(jì)的工具 OptionalBean ,那么上述的調(diào)用可以簡化成這樣:

public static void main(String[] args) {

    User axin = new User();

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

    axin.setName("hello");

    // 1. 基本調(diào)用

    String value1 = OptionalBean.ofNullable(axin)

            .getBean(User::getSchool)

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

    System.out.println(value1);

}

執(zhí)行結(jié)果: 其中User的school變量為空,可以看到代碼并沒有空指針,而是返回了null。這個(gè)工具怎么實(shí)現(xiàn)的呢?

OptionalBean 工具

/**

@author Axin

@since 2020-09-10

@summary 鏈?zhǔn)秸{(diào)用 bean 中 value 的方法

*/


public final class OptionalBean<T> {

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

    private final T value;

    private OptionalBean() {

        this.value = null;

    }

    /**

     * 空值會(huì)拋出空指針

     * @param value

     */


    private OptionalBean(T value) {

        this.value = Objects.requireNonNull(value);

    }

    /**

     * 包裝一個(gè)不能為空的 bean

     * @param value

     * @param <T>

     * @return

     */


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

        return new OptionalBean<>(value);

    }

    /**

     * 包裝一個(gè)可能為空的 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;

    }

    /**

     * 取出一個(gè)可能為空的對象

     * @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));

    }

    /**

     * 如果目標(biāo)值為空 獲取一個(gè)默認(rèn)值

     * @param other

     * @return

     */


    public T orElse(T other) {

        return value != null ? value : other;

    }

    /**

     * 如果目標(biāo)值為空 通過lambda表達(dá)式獲取一個(gè)值

     * @param other

     * @return

     */


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

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

    }

    /**

     * 如果目標(biāo)值為空 拋出一個(gè)異常

     * @param exceptionSupplier

     * @param <X>

     * @return

     * @throws X

     */


    public <X extends Throwable> 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;

    }

}

工具設(shè)計(jì)主要參考了 Optional 的實(shí)現(xiàn),再加上對鏈?zhǔn)秸{(diào)用的擴(kuò)展就是上述的OptionalBean。 getBean 其實(shí)是當(dāng)變量為空時(shí)返回了一個(gè) 包裝空值的 OptionalBean 對象,同時(shí)泛型的使用讓工具更加易用。

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

public static void main(String[] args) {

    User axin = new User();

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

    axin.setName("hello");

    // 1. 基本調(diào)用

    String value1 = OptionalBean.ofNullable(axin)

            .getBean(User::getSchool)

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

    System.out.println(value1);

    // 2. 擴(kuò)展的 isPresent方法 用法與 Optional 一樣

    boolean present = OptionalBean.ofNullable(axin)

            .getBean(User::getSchool)

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

    System.out.println(present);

    // 3. 擴(kuò)展的 ifPresent 方法

    OptionalBean.ofNullable(axin)

            .getBean(User::getSchool)

            .getBean(User.School::getAdress)

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

    // 4. 擴(kuò)展的 orElse

    String value2 = OptionalBean.ofNullable(axin)

            .getBean(User::getSchool)

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

    System.out.println(value2);

    // 5. 擴(kuò)展的 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());

    }

}

run一下:

總結(jié) 設(shè)計(jì)了一種可以鏈?zhǔn)秸{(diào)用對象成員而無需判空的工具讓代碼更加的精準(zhǔn)和優(yōu)雅,如果本文設(shè)計(jì)的工具滿足了剛好解決你的困擾,那就在項(xiàng)目中使用吧! 如果您有更的設(shè)計(jì)或者文中有錯(cuò)誤,還請留言一起討論,互相進(jìn)步!


      

—————END—————



喜歡本文的朋友,歡迎關(guān)注公眾號 程序員小灰,收看更多精彩內(nèi)容

                     
點(diǎn)個(gè)[在看],是對小灰最大的支持!

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉