1. ホーム
  2. Android

java.util.Iterator java.util.List.iterator()' で null オブジェクト参照例外が発生した場合の解決策を紹介します。

2022-02-20 18:56:18
<パス

前文

イテレータ java.util.List.iterator()' で null オブジェクト参照問題が発生しました。のオブジェクト参照をイテレートすると、そのような例外が発生するらしい。 null コレクションを使用しています。コレクションをNULLにして終わりでいいのでしょうか?

全文表示

コード例

まず、私自身のコードの状況から説明します。コード例は次のとおりです。
必要なビーンクラスは2つ。

// Garbage class
public class RubbishBean {
    private String mName;

    public RubbishBean(String name) {
        mName = name;
    }

    public String getName() {
        return mName == null ? "" : mName;
    }

    public void setName(String name) {
        mName = name;
    }

    @Override
    public String toString() {
        return "RubbishBean{" +
                "mName='" + mName + '\'' +
                '}';
    }
}

// Rubbish category class
public class RubbishCategory {
    private String mType;
    private List
 mRubbishBeanList;

    public RubbishCategory(String type, List
 rubbishBeanList) {
        mType = type;
        mRubbishBeanList = rubbishBeanList;
    }

    public String getType() {
        return mType == null ? "" : mType;
    }

    public void setType(String type) {
        mType = type;
    }

    public List
 getRubbishBeanList() {
        return mRubbishBeanList;
    }

    public void setRubbishBeanList(List
 rubbishBeanList) {
        mRubbishBeanList = rubbishBeanList;
    }
}


List
 rubbishCategoryList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    List
 rubbishBeans = null;
    rubbishBeans = new ArrayList<>();
    rubbishBeans.add(new RubbishBean("rubbishbean" + i));
    rubbishCategoryList.add(new RubbishCategory("type" + i, rubbishBeans));
}
for (RubbishCategory rubbishCategory : rubbishCategoryList) {
    List
 rubbishBeanList = rubbishCategory.getRubbishBeanList();
    for (RubbishBean rubbishBean : rubbishBeanList) {
        Log.d("tag",rubbishBean.toString());
    }
}


テストコードは以下の通りです。

D/tag: RubbishBean{mName='rubbishbean0'}
D/tag: RubbishBean{mName='rubbishbean1'}
D/tag: RubbishBean{mName='rubbishbean2'}
D/tag: RubbishBean{mName='rubbishbean3'}
D/tag: RubbishBean{mName='rubbishbean4'}


コードは単純で、コレクションを初期化し、それを繰り返し処理します。実行し、ログを見てください。

List
 rubbishCategoryList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    List
 rubbishBeans = null;
    if (i ! = 3) {
        rubbishBeans = new ArrayList<>();
        rubbishBeans.add(new RubbishBean("rubbishbean" + i));
    }
    // When it's the 4th element, no longer initialize rubbishBeans, i.e. leave it still null.
    rubbishCategoryList.add(new RubbishCategory("type" + i, rubbishBeans));
}
for (RubbishCategory rubbishCategory : rubbishCategoryList) {
    List
 rubbishBeanList = rubbishCategory.getRubbishBeanList();
    for (RubbishBean rubbishBean : rubbishBeanList) {
        Log.d("tag", rubbishBean.toString());
    }
}


ご覧の通り、これで問題ありません。
では、次にコードを修正します。

 E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.wzc.myblogdemos, PID: 24371
 NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference


変更点については、上記のコメントをご確認ください。で実行し、ログを確認してください。

RubbishCategory

これこそ、私たちが分析したいエラーではないでしょうか?

最適化1

を修正することが可能です。 mRubbishBeanList クラスを getter フィールドの public List getRubbishBeanList() { return mRubbishBeanList ! = null ? mRubbishBeanList : new ArrayList (); } メソッドを使用して、この例外を回避することができます。

D/tag: RubbishBean{mName='rubbishbean0'}
D/tag: RubbishBean{mName='rubbishbean1'}
D/tag: RubbishBean{mName='rubbishbean2'}
D/tag: RubbishBean{mName='rubbishbean4'}


もう一度コードを実行し、以下のログを表示します。

mRubbishBeanList

エラーはなくなり、結果も正常に印刷されるようになりました。ただ、4番目の要素がないだけです。

最適化2

しかし、実際に開発をしてみると、このように null コレクションをトラバースすると、なぜか RubbishCategory の値は、トラバーサル中に?この状況を実証することができないのです。おそらくは mRubbishBeanList カテゴリ setter フィールドの setter メソッドを使用すると、次のようになります。 public void setRubbishBeanList(List rubbishBeanList) { mRubbishBeanList = rubbishBeanList; } メソッドを使用します。

RubbishBean

のためにスキャンされたデータベースを取る。 RubbishCategory のセットを割り当てます。 mRubbishBeanList オブジェクトの mRubbishBeanList フィールド、すなわち RubbishBean フィールドが指すのは RubbishBean コレクションを作成します。何か問題があるのでしょうか?
はい、もしデータベースをスキャンして null が設定されている場合 mRubbishBeanList とすると null フィールドも setter ? ということが起こり得ます。
では、このような事態を避けるにはどうしたらよいのでしょうか。最適化する private List mRubbishBeanList = new ArrayList<>(); public void setRubbishBeanList(List rubbishBeanList) { if (rubbishBeanList ! = null) { mRubbishBeanList.clear(); mRubbishBeanList.addAll(rubbishBeanList); } } メソッドを使用します。

main

これにより、上記の例外が発生するのを効果的に防ぐことができます。

最後に

開発中に遭遇した問題を文書化、お役に立てれば幸いです。また、上に出てくる例外は、もしそれが Exception in thread "main" java.lang.NullPointerException メソッドが実証されている場合、出力される例外は

Exception in thread "main" java.lang.NullPointerException


Android環境で出力される例外処理ほど豊富ではありません。これも、私がテストしてわかったことです。