2016-11-26 4 views
-1

処理するのに最適なパターンを探していますNPE(Null Pointer Exception)。 Web API呼び出しのためにretrofitを使用していますが、いくつかのフィールドがnullである可能性があります。またnull配列の可能性もあります。 私が探しているのは、一度にすべてを処理する方法はありますか。nullポインタ例外を処理するためのベストパターン

などです。私はしようとすると、

モデルクラス

public class ModelClass{ 
    String name; 
    String email; 
    List<Items> items; 
} 

JSONファイル

{ 
    name:null, 
    email:"[email protected]", 
Items:[] 
} 

のでデシリアライズJSONファイルの後に、のsetTextはTextViewにするobject.getName()それは私がモデルクラスの非常に大規模なコレクションを持っており、実質的に使用している間のtry {}キャッチ()の各フィールドを配置する間違っているNPE

を介しますそれ。 このようなシナリオを処理するには、より良い方法がありますか。

+1

nullを返し、例外をスローしません。 –

+1

NullPointerExceptionsは処理しません。あなたはそれらを捕まえません。あなたはそれらを避ける。参照がnullの場合、その参照でメソッドを呼び出す前にnullをチェックします。 –

+0

基本的にobject.getName()はnullを返します。right ...私がしたいのはnullの代わりに空の文字列またはnullの配列リストを空のarraylistに変換したいのです。 – Techierj

答えて

1

Optionalの周りに包み込みます。これにより、値がnullの場合の処理​​をコンパイル時に決定するようになります。

Optional<String> optionalName = Optional.ofNullable(person.getName()); 

あなたはその後、例えば、に決めることができます。

  • は、デフォルト値を指定します。String name = optionalName.orElse("Bob");
  • は、あなたが選んだの例外をスロー:String name = optionalName.orElseThrow(() -> new IllegalArgumentException("Invalid name"));
+0

私はアンドロイドで使用できますか?私は、 'java 8'のいくつかの機能だけがアンドロイドで'利用可能 'であると思っています – Techierj

+0

それを試してみてください!そうでない場合、APIは簡単であり、独自の実装を設計できます。 –

+0

**アンドロイド**の 'api level 24'から*** *** ***をサポートしていただきありがとうございます。 – Techierj

0

は、デシリアライズにGsonライブラリを使用あなたのjsonファイルとそれはserializeNullsを呼び出すことによってnull項目自体を処理します。

これは(Googleによる)Gsonライブラリの適切なガイドラインです:あなたはencapsulationを使用する必要があり、すべての https://futurestud.io/tutorials/gson-getting-started-with-java-json-serialization-deserialization

+0

こんにちはpayam ,,,私はすでにこの投稿[リンク](https://futurestud.io/tutorials/gson-builder-force-serialization-of-null-values)を見ている..しかし、電子メールフィールドの値を確認するまだnullです... Stringにはデフォルト値nullがあるためです。 NPE – Techierj

+0

の管理に役立たず、あなたの要求を満たしていませんか? –

+0

いいえ、それは 'GSon'で' nullable'を許可するとデフォルト値を取ることができ、Stringは** null **デフォルト値なので、ここでは仕事をしたいからです。 – Techierj

-1

まず。変数がprivate/protectedであり、公平getterssettersがあることを意味します。そのよう

public class ModelClass{ 
    private String name; 
    private String email; 
    private List<Items> items; 
    public ModelClass(){ 
     items = new List<Items>(); 
    } 
    public String getName(){ 
     return name != null?name:""; 
    } 
    public void setName(String name){ 
     this.name = name; 
    } 
    public String getEmail(){ 
     return email=null?email:""; 
    } 
    public void setEmail(String email){ 
     this.email= email; 
    } 
    public Items getItem(int index){ 
     return items!=null?items.get(index):null; 
    } 
    public boolean addItem(Items item){ 
     return items!=null?items.add(item):false; 
    } 
} 

あなたはlistが今constructorに初期化されます見ることができるように。したがって、外部のクラスはItemsを追加または取得することしかできません。何らかの理由でリストがnullの場合、getteradderNPEを投げる代わりにそれぞれnullとfalseを返します。基本的にserializationまたはdeserializationを使用している場合は、constructor内のObjectsStringsは除く)をすべて初期化する必要があります。本質的にfieldがヌルになる可能性がある場合は、チェックする必要があります。

また、Java Naming Conventionsによれば、Items class:Item,Classesという名前は、アイテムのコレクションを保持している場合にのみ複数の名前にすることができます。たとえば:valueOf

public class Item{ 
    private String field; 
    public Item(){ 
      field = "hello"; 
    } 
} 

public class Items{ 
    private List<Item> items; 
    public Items(){ 
      items = new List<Item>(); 
    } 
} 

最後に、私はまたString方法を見てみた推薦します。表示されているように、このメソッドは、渡された変数がnullであるかどうかをチェックし、そうでない場合には文字列valueを返します。似たようなものを使うことができます。

+0

あなたは100モデルクラスがあれば、各モデルクラスのgetter()setter()でそれらをチェックする必要があります...それを行うには良い方法だと思いますか? – Techierj

+0

@Techierjコンストラクタの '90%'で 'Object'をすべて初期化すると、チェックしなくても問題はないはずです。 (他の10個は、 'Files'、' Connections'などのように、初期化中に 'Exceptions'を投げる' Objects'を使うときです。しかし、すべての 'Java'プロジェクトでは、すべての'非静的フィールド 'に対して' Getters'と 'Setters'を使うべきです。 –

+0

こんにちは 'オプションは参考になるだろう'アンドロイド。そして私はdn knw who downvote誰にも返信ありがとう:( – Techierj

0

NPEを迷惑にならないようにしたい場合は、自分でjsonファイルをデシリアライズするときにinit値を使用できます。たとえば、逆シリアル化されたnameがnullの場合、そのようなinit name = ""だけです。これで、すべてのモデルクラスに触れる必要はなく、デシリアライズメソッドを変更するだけです。これによりNPEを防ぐことができます。

0

これは1か所で行うことをお勧めしません。最良の方法は、あなたがそのフィールドを使う前にnullをチェックすることです。そうでなければgsonのようなlibsがこれを行います。また、json文字列が深い階層を持つ可能性があるため、すべての空文字列を ""に置き換えるのは効率的でエレガントではありません。ですから、もし@ myoldgrandpaの答えがうまくいくならば、あなたがそうしたいと思うなら、それはおそらく最良の方法です。