導入
NPE(nullpointerexception)は、デバッグプログラムで最も一般的な例外です。 Googleは、メソッドがnullを返すか、新しいオブジェクトを返すべきかについて多くの議論をしています。
記事の冒頭で、最初にNPEの問題について話しましょう。 NPEの問題は、開発でしばしば遭遇するnullpointerexceptionです。 2つのクラスがあり、UMLクラスの図が次の図に示されているとします
この場合、次のコードがあります
user.getAddress()。getProvince();
この執筆方法は、ユーザーがnullであるときにnullpointerexceptionを報告する場合があります。この問題を解決するために、次の記述方法が採用されています
if(user!= null){アドレスアドレス= user.getAddress(); if(address!= null){string gunt = address.getProvince(); }}この執筆スタイルは比較的醜いです。上記の醜いライティングスタイルを避けるために、醜いデザインはエレガントになります。 Java8は、このライティング方法を最適化するためのオプションのクラスを提供し、次のテキストセクションについて詳しく説明します。
APIはじめに
最初にAPIを紹介させてください。他の記事とは異なり、この記事は類推方法を採用し、ソースコードを組み合わせます。他の記事とは異なり、各APIリストにより、人々は重要なポイントを見つけることができません。
(1)optional(t value)、empty()、of(t value)、ofnullable(t value)
これらの4つの関数には相関があるため、メモリのグループに配置されます。
まず、オプション(t値)、つまりコンストラクターがプライベートな許可であり、外部的に呼ばれることはできないことを説明させてください。他の3つの関数は、私たちが呼び出すための公開許可です。次に、オプションの本質は、内部的に実際の価値を保存することであり、構築するときに、その値が空であるかどうかは直接判断されます。わかりました、それはまだかなり抽象的です。下の図に示すように、オプション(t値)コンストラクターのソースコードを直接アップロードします
次に、(t値)のソースコードは次のとおりです
public static <t> optional <t> of(t value){return new optional <>(value); }言い換えれば、コンストラクターは(t値)関数によって内部的に呼ばれます。コンストラクターのソースコードに基づいて、2つの結論を導入できます。
(1)値の値が空の場合、nullpointerexceptionは引き続き報告されます。
(2)of(t value)関数によって構築されたオプションオブジェクトは、値が空でない場合に正常に構築できます。
さらに、オプションのクラスは、おそらく次のように、値nullを持つオブジェクトも維持しています
パブリックファイナルクラスオプション<t> {// omit ...... private static final optional <?> empty = new optional <>(); private optional(){this.value = null; } // omit ... public static <t> optional <t> empty(){@suppresswarnings( "unchecked")optional <t> t =(optional <t>)empty; tを返します。 }}次に、empty()の関数は、空のオブジェクトを返すことです。
まあ、非常に多くの準備が敷設されています。 of ofnullable(t value)に関数があり、ソースコードが追加されていると言えます。
public static <t> optional <t> ofnullable(t value){return値== null? empty():of(value); }まあ、誰もがそれが何を意味するのかを理解する必要があります。 (t値)と比較した違いは、値値がnullの場合、(t値)がnullpointerexceptionを報告することです。 ofnullable(t value)は例外をスローしません。
それは、プロジェクトで機能の代わりにヌル可能な関数のみを使用することを意味しますか?
いいえ、何かが存在する場合、それは自然に価値を持っています。走っているときは、nullpointerexceptionを隠したくありません。代わりに、すぐに報告する必要があります。この場合、機能を使用します。しかし、私はそのようなシーンがほとんどないことを認めなければなりません。ブロガーは、この関数をJunitテストケースの書面でのみ使用しています。
(2)orelse(t other)、orelseget(supplier <?extends t> other)、orelsethrow(supplier <?extends x>例外サプライヤー)
これらの3つの機能はグループで記憶されており、コンストラクターによって渡された値がnullである場合に呼び出されます。 OrelseとOrelsegetの使用は次のとおりです。値がnullの場合、デフォルト値が与えられます。
@testpublic void test(){user user = null; user = optional.ofnullable(user).orelse(createUser()); user = optional.ofnullable(user).orelseget(() - > createUser()); } public user createUser(){user user = new user(); user.setName( "Zhangsan");ユーザーを返します;}これら2つの関数の違い:ユーザー値がnullでない場合、Orelse関数はcreateUser()メソッドを実行しますが、Orelseget関数はcreateUser()メソッドを実行しないため、自分でテストできます。
Orelsethrowについては、値がnullの場合、例外が直接捨てられます。使用法は次のとおりです
ユーザーユーザー= null; optional.ofnullable(user).orelsethrow(() - > new Exception( "ユーザーは存在しない"));
(3)Map(function <?super t、?extends u> mapper)およびflatmap(function <?super t、optional <u >> mapper)
これらの2つの関数はメモリのセットに配置され、これら2つの関数は値を変換する操作を行います。
ソースコードを直接アップロードします
public final class optional <t> {// omit ...... 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)); }} // omit ... public <u> optional <u> flatmap(function <?super t、optional <u >> mapper){objects.requirenonnull(mapper); if(!ispresent())return empty(); else {return objects.requirenonnull(mapper.apply(value)); }}}関数の本体にこれら2つの関数に違いはありません。唯一の違いは、エントリパラメーターです。マップ関数によって受け入れられるエントリパラメータータイプは関数です<?スーパーT、? u>を拡張しますが、flapmapの入力パラメータータイプは関数です<?スーパーT、オプション<U >>。
特定の使用法に関しては、マップの場合:
ユーザー構造が次の場合
パブリッククラスユーザー{プライベート文字列名; public string getName(){return name; }}この時点で、名前を取る執筆方法は次のとおりです
string city = optional.ofnullable(user).map(u-> u.getname())。get();
フラットマップの場合:
ユーザー構造が次の場合
パブリッククラスユーザー{プライベート文字列名; public Optional <String> getName(){return optional.ofnullable(name); }}この時点で、名前を取る執筆方法は次のとおりです
string city = optional.ofnullable(user).flatmap(u-> u.getname())。get();
(4)ispresent()およびifpresent(Consumer <?super t> Consumer)
これらの2つの機能をまとめて、それらを記憶します。 Ispresentは、値が空であるかどうかを判断することを意味し、Ifpresentは値が空でない場合に何らかの操作を行うことを意味します。これら2つの関数のソースコードは次のとおりです
パブリックファイナルクラスオプション<t> {// omit ...... public boolean ispresent(){return value!= null; } // omit ... public void ifpresent(Consumer <?super t> consumer){if(value!= null)consumer.accept(value); }}追加の説明が必要です
if(user!= null){// todo:何かをする}書かれています
user user = optional.ofnullable(user); if(optional.ispresent()){// todo:何かをする}このため、コード構造は依然として醜いです。ブロガーは、後で正しい執筆方法を提供します
ifpresent(Consumer <?super t> Consumer)については、以下に示すように使用も非常に簡単です
optional.ofnullable(user).ifpresent(u-> {// todo:do something});(5)フィルター(述語<?スーパーt>予測)
それ以上のADOなしで、ソースコードをアップロードしてください
パブリックファイナルクラスオプション<t> {// omit ...... objects.requirenonnull(predicate); if(!ispresent())これを返します。それ以外の場合は、predict.test(value)を返しますか?これ:empty();}フィルターメソッドは、オプションに含まれる値をフィルタリングする述語を受け入れます。含まれる値が条件を満たしている場合、オプションは引き続き返されます。それ以外の場合は、オプションのhemptyが返されます。
使用法は次のとおりです
optional <user> user1 = optional.ofnullable(user).filter(u-> u.getname()。length()<6);
上記のように、ユーザーの名前の長さが6未満の場合は、返されます。 6を超える場合、空のオブジェクトが返されます。
実用
例1
関数メソッド
以前の執筆
public string getCity(user user)throws exception {if(user!= null){if(user.getaddress()!= null){address address = user.getAddress(); if(address.getCity()!= null){return address.getCity(); }}} new Expection( "Value Error"); }Java8ライティング方法
public string getCity(user user)throws exception {return optional.ofnullable(user).map(u-> u.getaddress()).map(a-> a.getcity()).orelsethrow(() - > new Expertion( "fetch error");}例2
たとえば、メインプログラムで
以前の執筆
if(user!= null){dosomething(user);}Java8ライティング方法
optional.ofnullable(user).ifpresent(u-> {dosomething(u);});例3
以前の執筆
public user getUser(user user)throws Exception {if(user!= null){string name = user.getName(); if( "zhangsan" .equals(name)){return user; }} else {user = new user(); user.setName( "Zhangsan");ユーザーを返します。 }}Java8ライティング方法
public user getUser(user user){return optional.ofnullable(user).filter(u-> "zhangsan" .equals(u.getname())).orelseget(() - > {user user1 = new user(); user1.setname( "zhangsan"); return user1;};};}他の例は1つずつリストされません。ただし、ブロガーは、このチェーンプログラミングを使用することは実際にコードでエレガントであると考えています。ただし、ロジックはそれほど明白ではなく、読みやすさは低下します。プロジェクトの状況に応じて使用します。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。