HomeJavaNullPointerExceptionとJavaの基本

JavaにおけるNullPointerExceptionをはじめとした例外他、簡単なサンプルコードなどを掲載しています。

NullPointerExceptionとJavaの基本

NullPointerExceptionについて

Javaエンジニアの方で、一度もNullPointerExceptionに遭遇したことがないという方はいないと思います。 それぐらい、よく見られる例外です。
NullPointerExceptionは、インスタンスへの参照がない値に問い合わせた際に発生する例外です。
具体的に、以下のようなコードでNullPointerExceptionが発生します。

String str1 = "";
String str2 = null;
System.out.println("start ...");
System.out.println("str1.length : " + str1.length());
System.out.println("str2.length : " + str2.length());

上記プログラムはコンパイルエラーにはなりませんが、実行すると、最後の
System.out.println("str2.length : " + str2.length());
でNullPointerExceptionが発生します。
正確には、str2.length();で発生します。

管理人自身、まず最初につまづいたところでしたが
""(空文字:型はString型)とnullの違いがよくわかる例だと思います。
""というのはあくまでObject型を継承したString型であるため、
length()メソッドを使えますし、equals(Object)メソッドも使えるし、substringメソッドも使えます。

しかし、nullはそれ以外の何者でもないため、いかなるメソッドも使えません。
そのnullでメソッドを実行させようとして発生する例外がNullPointerExceptionです。
もう少し開発よりのコードにして実際の開発でNullPointerExceptionが発生するのは、
以下のようなケースもあります。

/*
 * UserInfoDao#selectUserInfo(userId)で
 * DBに問合せた結果を取得する
 */
long userId = 12345L;
    UserInfoDao userInfoDao = new UserInfoDao();
List userList = userInfoDao.selectUserInfo(userId);

String userName = "";
if(userList.size() != 0) {
    userName = userList.get(0).getUserName();
}

上記コードで、userListの戻り値が、仮にnullであった場合、どこでNullPointerExceptionが発生するでしょうか。 userName = userList.get(0).getUserName(); でしょうか。

答えは、ifの判定を行う際の
userList.size()  で発生します。
size()メソッドを実行できずにNullPointerExceptionが発生します。

nullはいかなるメソッドも使えません。

実装ではArrayList型であることを期待して実装していますが、
実際はnullであるためNullPointerExceptionが発生します。
他にもSeasar2のようなフレームワークでDIコンテナ(diconファイル)などに設定して
インスタンスを取得するようになっているケースで
スペルミス等が原因でインスタンスを取得できずにNullPointerExceptionが発生したりもします。

想定した型の器はあるにも関わらず、中身がなく(nullであり)、
nullに問い合わせる(主にはメソッドを呼び出す)場合に発生します。
将来セットされる値まで保持可能な大きな「器」を作り、
そこに適宜「中身」を入れていくという考え方自体に危うさが潜んでいます。
・・・そうすると、nullチェックが必要、ということで
NullPointerExceptionを発生させないため、
以下のように対策するとします。

long userId = 12345L:
UserInfoDao userInfoDao = new UserInfoDao();
List userList
    = userInfoDao.selectUserInfo(userId);

String userName = "";

if(userList.size() != 0 && userList != null) {
    userName = userList.get(0).getUserName();
}

if文を修正して、userListのnullチェックを実施したから
もうNullPointerExceptionは発生しないだろう、と思われる方も
いるかも(いないかも?)しれません。
上記コードでは、userListが仮にnullだった場合、NullPointerExceptionが発生します。
これもJavaの基本ですが、if文は左から順に条件を判定するためです。
上記コードでは、やはりuserList.size()を実行しようとして、
NullPointerExceptionが発生します。
以下のようにすることで、NullPointerExceptionを発生させず
期待の動作をさせることができます。

long userId = 12345L:
UserInfoDao userInfoDao = new UserInfoDao();

List userList
    = userInfoDao.selectUserInfo(userId);

String userName = "";
if(userList != null && userList.size() != 0) {
    userName = userList.get(0).getUserName();
}

これでバッチリ、例外なく動作せられます。
まず、userListがnullでないことを確認し、その後でsize()メソッドを使っているため
ここではNullPointerExceptionは発生しません。
userList != null というのは、メソッドを使わずに判定しているため
NullPointerExceptionが発生することはありません。

NullPointerExceptionが発生してしまう原因は、
器を用意しセットしたが、そのセットした値がObjectではなく結局nullになっていて
そのメソッドを実行させようとして発生する例外であることが伝えられればと思います。
Javaトップへ

ページトップへ

トピックアップ メニュー

トピックアップ リンク

Copyright (C) トピックアップ All Rights Reserved.
inserted by FC2 system