目錄
NullObject模式
什麼是NullObject模式呢?
.NR Null Object
讓我們來看一個使用範例:
那麼要如何來獲得這款外掛呢?
安裝方式
使用Optional具有如下优点:
但是也同样具有一些缺点:
首頁 Java java教程 Java判空如何實現

Java判空如何實現

Apr 22, 2023 pm 06:46 PM
java

NullObject模式

對於專案中無數次的判空,對程式碼品質整齊度產生了十分之惡劣的影響,對於這種現象,我們稱之為「判空災難」。

那麼,這種現像如何治理呢,你可能聽過NullObject模式,不過這不是我們今天的武器,但還是需要介紹一下NullObject模式。

什麼是NullObject模式呢?

In  object-oriented computer programming, a null object is an object with  no referenced value or with defined neutral ("null") an object with  no referenced value or with defined neutral ("null") behavior. The null  object behavior (or lack thereof).

以上解析來自Wikipedia。

NullObject模式首次發表在「程式設計模式語言 」系列叢書中。一般的,在物件導向語言中,物件的呼叫前需要使用判空檢查,來判斷這些物件是否為空,因為在空引用上無法呼叫所需方法。

範例程式碼如下(命名來自網絡,哈哈到底是有多懶):

Nullable是空物件的相關操作接口,用於確定物件是否為空,因為在空物件模式中,物件為空會被包裝成一個Object,成為Null Object,該物件會對原有物件的所有方法進行空實作…

public interface Nullable {      boolean isNull(); }
登入後複製

這個介面定義了業務物件的行為。

 <br>
登入後複製
public interface DependencyBase extends Nullable {      void Operation();  }
登入後複製

這是該物件的真實類,實作了業務行為介面DependencyBase與空物件操作介面Nullable。

public class Dependency implements DependencyBase, Nullable {      @Override     public void Operation() {         System.out.print("Test!");     }      @Override     public boolean isNull() {         return false;     }  }
登入後複製

這是空對象,對原有對象的行為進行了空實現。

public class NullObject implements DependencyBase{      @Override     public void Operation() {         // do nothing     }      @Override     public boolean isNull() {         return true;     }  }
登入後複製

在使用時,可以透過工廠調用方式來進行空物件的調用,也可以透過其他如反射的方式對物件進行調用(一般多耗時幾毫秒)在此不進行詳細敘述。

public class Factory {      public static DependencyBase get(Nullable dependencyBase){         if (dependencyBase == null){             return new NullObject();         }         return new Dependency();     }  }
登入後複製

這是一個使用範例,透過這個模式,我們不再需要進行物件的判空操作,而是可以直接使用對象,也不必擔心NPE(NullPointerException)的問題。

public class Client {      public void test(DependencyBase dependencyBase){         Factory.get(dependencyBase).Operation();     }  }
登入後複製
.NR Null Object

NR  Null Object是一款適用於Android Studio、IntelliJ  IDEA、PhpStorm、WebStorm、PyCharm、RubyMine、AppCode、CLion、GoLand、DataGrip等IDEA的Intellij插件。其可依據現有對象,便捷快速產生其空對像模式所需的組成成分,其包含功能如下:

  1. 分析所選類別可宣告為介面的方法;

  2. 抽像出公有介面;

  3. 建立空對象,自動實作公有介面;

  4. 對部分函數進行可為空宣告;

  5. 可追加函數進行再次產生;

  6. 自動的函數命名規範

讓我們來看一個使用範例:

Java判空如何實現

怎麼樣,看起來是不是非常快速便捷,只需要在原有需要進行多次判空的對象中,郵件彈出選單,選擇Generate,並選擇NR Null Object即可自動產生對應的空物件元件。

那麼要如何來獲得這款外掛呢?
安裝方式

可以直接透過IDEA的Preferences中的Plugins倉庫來安裝。

選擇Preferences → Plugins → Browse repositories

Java判空如何實現

##搜尋「NR Null Oject」或「Null Oject」進行模糊查詢,點選右側的Install,restart IDEA即可。

Java判空如何實現

Optional

還有一種方式是使用Java8特性中的Optional來進行優雅地判空,Optional來自官方的介紹如下:

A  container object which may or may not contain a non-null value. If a  value is present, isPresent() will return true and get() will return the #value.

#value.

# #一個可能包含也可能不包含非null值的容器物件。如果存在值,isPresent()將傳回true,get()將傳回該值。

話不多說,舉個例子。

有以下程式碼,需要取得Test2中的Info信息,但是參數為Test4,我們要一層層的申請,每一層都獲得的物件都可能是空,最後的程式碼看起來就像這樣。

  

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">public String testSimple(Test4 test) {        if (test == null) {            return &quot;&quot;;        }        if (test.getTest3() == null) {            return &quot;&quot;;        }        if (test.getTest3().getTest2() == null) {            return &quot;&quot;;        }        if (test.getTest3().getTest2().getInfo() == null) {            return &quot;&quot;;        }        return test.getTest3().getTest2().getInfo();    }</pre><div class="contentsignin">登入後複製</div></div>但是使用Optional後,整個就都不一樣了。

    

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">public String testOptional(Test test) {         return Optional.ofNullable(test).flatMap(Test::getTest3)                 .flatMap(Test3::getTest2)                 .map(Test2::getInfo)                 .orElse(&quot;&quot;);     }</pre><div class="contentsignin">登入後複製</div></div>1、Optional.ofNullable(test),如果test為空,則傳回一個單例空Optional對象,如果非空則傳回一個Optional包裝對象,Optional將test包裝;

    

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">public static &lt;t&gt; Optional&lt;t&gt; ofNullable(T value) {         return value == null ? empty() : of(value);     }&lt;/t&gt;&lt;/t&gt;</pre><div class="contentsignin">登入後複製</div></div>2、flatMap(Test::getTest3)判斷test是否為空,如果為空,繼續返回第一步中的單例Optional對象,否則呼叫Test的getTest3方法;

    

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">public&lt;u&gt; Optional&lt;u&gt; flatMap(Function super T, Optional&lt;u&gt;&gt; mapper) {         Objects.requireNonNull(mapper);         if (!isPresent())             return empty();         else {             return Objects.requireNonNull(mapper.apply(value));         }     }&lt;/u&gt;&lt;/u&gt;&lt;/u&gt;</pre><div class="contentsignin">登入後複製</div></div> <p>3、flatMap(Test3::getTest2)同上调用Test3的getTest2方法;</p> <p>4、map(Test2::getInfo)同flatMap类似,但是flatMap要求Test3::getTest2返回值为Optional类型,而map不需要,flatMap不会多层包装,map返回会再次包装Optional;<code>  

public<u> Optional<u> map(Function super T, ? extends U> mapper) {        Objects.requireNonNull(mapper);        if (!isPresent())            return empty();        else {            return Optional.ofNullable(mapper.apply(value));        }    }</u></u>
登入後複製

5、orElse("");获得map中的value,不为空则直接返回value,为空则返回传入的参数作为默认值。

public T orElse(T other) {     return value != null ? value : other; }
登入後複製

怎么样,使用Optional后我们的代码是不是瞬间变得非常整洁,或许看到这段代码你会有很多疑问,针对复杂的一长串判空,Optional有它的优势,但是对于简单的判空使用Optional也会增加代码的阅读成本、编码量以及团队新成员的学习成本。毕竟Optional在现在还并没有像RxJava那样流行,它还拥有一定的局限性。

如果直接使用Java8中的Optional,需要保证安卓API级别在24及以上。

Java判空如何實現

你也可以直接引入Google的Guava。(啥是Guava?来自官方的提示)

Guava  is a set of core libraries that includes new collection types (such as  multimap and multiset), immutable collections, a graph library,  functional types, an in-memory cache, and APIs/utilities for  concurrency, I/O, hashing, primitives, reflection, string processing,  and much more!

引用方式,就像这样:    

dependencies {       compile 'com.google.guava:guava:27.0-jre'       // or, for Android:       api 'com.google.guava:guava:27.0-android'     }
登入後複製

不过IDEA默认会显示黄色,提示让你将Guava表达式迁移到Java Api上。

Java判空如何實現

当然,你也可以通过在Preferences搜索"Guava"来Kill掉这个Yellow的提示。

Java判空如何實現

使用Optional具有如下优点:
  1. 将防御式编程代码完美包装

  2. 链式调用

  3. 有效避免程序代码中的空指针

但是也同样具有一些缺点:
  1. 流行性不是非常理想,团队新成员需要学习成本

  2. 安卓中需要引入Guava,需要团队每个人处理IDEA默认提示,或者忍受黄色提示

当然,Kotlin以具有优秀的空安全性为一大特色,并可以与Java很好的混合使用,like this:    

test1?.test2?.test3?.test4
登入後複製

以上是Java判空如何實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
兩個點博物館:所有展覽以及在哪裡可以找到它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java 中的平方根 Java 中的平方根 Aug 30, 2024 pm 04:26 PM

Java 中的平方根指南。下面我們分別透過例子和程式碼實作來討論平方根在Java中的工作原理。

Java 中的完美數 Java 中的完美數 Aug 30, 2024 pm 04:28 PM

Java 完美數指南。這裡我們討論定義,如何在 Java 中檢查完美數?

Java 中的隨機數產生器 Java 中的隨機數產生器 Aug 30, 2024 pm 04:27 PM

Java 隨機數產生器指南。在這裡,我們透過範例討論 Java 中的函數,並透過範例討論兩個不同的生成器。

Java 中的阿姆斯壯數 Java 中的阿姆斯壯數 Aug 30, 2024 pm 04:26 PM

Java 中的阿姆斯壯數指南。這裡我們討論一下java中阿姆斯壯數的介紹以及一些程式碼。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。這裡我們透過範例討論簡介、如何使用 weka java、平台類型和優點。

Java 中的史密斯數 Java 中的史密斯數 Aug 30, 2024 pm 04:28 PM

Java 史密斯數指南。這裡我們討論定義,如何在Java中檢查史密斯號?帶有程式碼實現的範例。

Java Spring 面試題 Java Spring 面試題 Aug 30, 2024 pm 04:29 PM

在本文中,我們保留了最常被問到的 Java Spring 面試問題及其詳細答案。這樣你就可以順利通過面試。

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

See all articles