java.lang.NullPointerExceptionは、Javaプログラミングで最も一般的な例外の一つです。Javaで作業している人なら誰でも、JavaのスタンドアロンプログラムやJavaウェブアプリケーションで突如としてこれが現れるのを見たことがあるでしょう。
java.lang.NullPointerException
NullPointerExceptionはランタイム例外なので、プログラムでそれをキャッチする必要はありません。アプリケーションでNullPointerExceptionが発生するのは、オブジェクトが必要なところでnullに対して何らかの操作をしようとしているときです。JavaプログラムでNullPointerExceptionが発生する一般的な理由は次のとおりです:
- オブジェクトのインスタンスに対してメソッドを呼び出していますが、ランタイムではそのオブジェクトがnullです。
- ランタイムでnullのオブジェクトインスタンスの変数にアクセスしています。
- プログラムでnullをスローしています。
- nullの配列のインデックスにアクセスしたり、その値を変更したりしています。
- ランタイムでnullの配列の長さを確認しています。
Java NullPointerExceptionの例
1. JavaプログラムでのNullPointerExceptionの例を見てみましょう。
1. インスタンスメソッドを呼び出すときのNullPointerException
上記のプログラムを実行すると、次のNullPointerExceptionエラーメッセージがスローされます。
ここで、ステートメントt.foo("Hi");
でNullPointerExceptionが発生しています。これは、ここで「t」がnullであるためです。
2. ヌルオブジェクトのフィールドにアクセス/修正する際のJava NullPointerException
上記のプログラムは、次のNullPointerExceptionスタックトレースをスローします。
ここで、ステートメントint i = t.x;
でNullPointerExceptionがスローされます。これは、ここで「t」がnullであるためです。
3. メソッド引数にnullが渡される場合のJava NullPointerException
これはjava.lang.NullPointerException
の最も一般的な発生の1つです、なぜなら、null引数を渡しているのは呼び出し側だからです。
上記のプログラムがEclipse IDEで実行されたときに、下の画像はnullポインタ例外を示しています。
4. nullが投げられたときのjava.lang.NullPointerException
上記プログラムの例外スタックトレースは、throw null;
ステートメントのためにNullPointerExceptionを示しています。
5. null配列の長さを取得するときのNullPointerException
6. null配列のインデックス値にアクセスするときのNullPointerException
7. nullオブジェクトを同期化したときのNullPointerException
synchronized(mutex)
は、”mutex”オブジェクトがnullのため、NullPointerExceptionをスローします。
8. HTTPステータス500 java.lang.NullPointerException
時々、Java Webアプリケーションからエラーページの応答を受け取り、エラーメッセージが「HTTPステータス500 – 内部サーバーエラー」でルート原因がjava.lang.NullPointerException
となることがあります。
これに対して、Spring MVCの例プロジェクトを編集して、以下のようにHomeControllerメソッドを変更しました。
以下の画像は、Webアプリケーションの応答によってスローされたエラーメッセージを示しています。
例外のスタックトレースは以下のとおりです:
ルート原因は、user.getUserId()
がnullを返すため、user.getUserId().toLowerCase()
ステートメントでのNullPointerExceptionです。
java.lang.NullPointerExceptionの検出方法
NullPointerExceptionの検出は非常に簡単です。単に例外トレースを見れば、例外のクラス名と行番号が表示されます。次にコードを確認し、NullPointerExceptionの原因となる可能性があるnullを確認します。上記の例をすべて見れば、スタックトレースからnullポインタ例外の原因が非常に明確です。
NullPointerExceptionの修正方法
java.lang.NullPointerExceptionは未検査例外なので、キャッチする必要はありません。nullポインタ例外は、nullチェックと予防的なコーディングテクニックを使用して防ぐことができます。以下のコード例を見て、java.lang.NullPointerException
を回避する方法を示しています。
NullPointerExceptionを避けるためのコーディングのベストプラクティス
1. 以下の関数を考え、nullポインタ例外を引き起こすシナリオに注意してください。
引数がnullとして渡されると、NullPointerExceptionが発生する可能性があります。同じメソッドは、NullPointerExceptionを回避するために以下のように書くことができます。
2. 引数のためにnullチェックを追加し、必要に応じてIllegalArgumentException
をスローすることもできます。
3. 以下のコードのように三項演算子を使用することもできます。
4. toString()
メソッドの代わりにString.valueOf()
を使用してください。例えば、PrintStream println()メソッドのコードは以下のように定義されています。
以下のコードスニペットは、valueOf()メソッドがtoString()の代わりに使用されている例を示しています。
5. 可能な限りnullではなく、空のオブジェクトを返すメソッドを記述してください。例えば、空のリスト、空の文字列などです。
6. NullPointerExceptionを回避するために、コレクションクラスで定義されたいくつかのメソッドがあります。それらを使用するべきです。例えば、contains()、containsKey()、containsValue()などです。
参照: APIドキュメント
Source:
https://www.digitalocean.com/community/tutorials/java-lang-nullpointerexception