Javaで空判定を実装する方法

王林
リリース: 2023-04-22 18:46:16
転載
927 人が閲覧しました
NullObject モード

プロジェクト内で発生した無数の null 判定は、コードの品質とクリーンさに非常に悪影響を及ぼしており、私たちはこの現象を「null 判定災害」と呼んでいます。

それでは、この現象はどのように管理すればよいのでしょうか? NullObject パターンについて聞いたことがあるかもしれませんが、これは今日の私たちの武器ではありませんが、それでも NullObject パターンを導入する必要があります。

NullObject モードとは何ですか?

オブジェクト指向コンピュータ プログラミングでは、null オブジェクトは、参照される値がないか、中立 (「null」) の動作が定義されているオブジェクトです。null オブジェクトの設計パターンでは、そのようなオブジェクトの使用方法とそのオブジェクトの使い方について説明します。行動 (またはその欠如)。

上記の分析は Wikipedia から引用したものです。

NullObject パターンは、書籍「プログラミング パターン ランゲージ」シリーズで初めて出版されました。一般に、オブジェクト指向言語では、null 参照では必要なメソッドを呼び出すことができないため、オブジェクトを呼び出す前に null チェックを使用して、これらのオブジェクトが null かどうかを判断する必要があります。

サンプル コードは次のとおりです (名前はインターネットから来ています。笑、なんて怠け者でしょう):

Nullable は空のオブジェクトに関連する操作インターフェイスであり、空のオブジェクトに関連する操作インターフェイスです。オブジェクトは空です。空オブジェクト モードでは、オブジェクトが空の場合、オブジェクトはオブジェクトにパッケージ化され、Null オブジェクトになります。このオブジェクトは、元のオブジェクトのすべてのメソッドの null 実装を実装します...

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();     }  }
ログイン後にコピー

これは使用例です。このモードを使用すると、オブジェクトの null 操作を実行する必要がなくなり、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. 一部の関数では、null 許容宣言を作成します。

  5. 関数を追加して再生成できます。

  6. 自動関数命名規則

使用例を見てみましょう:

Javaで空判定を実装する方法

どうですか? とても速くて便利そうです。空にするだけで十分です。 -元のオブジェクトで複数回チェックされました。電子メール ポップアップ メニューで、[生成] を選択し、[NR Null オブジェクト] を選択して、対応する Null オブジェクト コンポーネントを自動的に生成します。

それでは、このプラグインを入手するにはどうすればよいでしょうか?
インストール方法

IDEA の環境設定のプラグイン リポジトリから直接インストールできます。

環境設定を選択 → プラグイン → リポジトリを参照

Javaで空判定を実装する方法

##あいまいクエリの場合は「NR Null Oject」または「Null Oject」を検索しますをクリックし、右側の「インストール」をクリックして IDEA を再起動します。

Javaで空判定を実装する方法

Optional

もう 1 つの方法は、Java8 機能の Optional を使用して、エレガントな空判定を実行することです。Optional の正式な紹介は次のとおりです。

#null 以外の値を含む場合と含まない場合があるコンテナ オブジェクト。値が存在する場合、isPresent() は true を返し、get() は値を返します。

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 パッケージング オブジェクトが返されます。 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 オブジェクトを返し続けます。そうでない場合は、呼び出します。テストの 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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート