前提知識
そもそもプログラムは、変数と呼ばれる「箱」にモノ(=値)を格納しておき、それらを取り出して別の「箱」に入っていたモノと比較したり、別の「箱」のモノと組み合わせたりというような処理ができる。そんな「箱」は大きく下記の2つに分類できる。
- 基本型…「決まったサイズの値」(=数値)を格納する
- 参照型…「場所」(=アドレス)を格納する
詳しくは下記の記事を参照して欲しい。
要は基本型の変数には具体的な数値を、参照型の変数にはアドレスが入っているという訳だ。数値については説明は不要だと思う。人間が数を数えるときに使う数字がそのまま入っており、負の数だったり、小数だったりも扱えるように工夫されている。
問題はアドレスだ。
ここで誤解しないで欲しいのは、基本型の変数にもアドレス情報は含まれているということだ。基本型の変数が意味するところというのは、結局のところ『指定のアドレスから指定のサイズの場所を確保した』という「箱」を準備したに過ぎないのだ。何故この説明をしたかといえば、基本型の変数を作成した時点でアドレスは自動的に割り振られて勝手に決定されるということを頭において欲しいからだ。
一方、参照型の変数の作成時点でのアドレスは(javaの場合)分からないのだ。そのため明示的にアドレスを渡していない状態での参照型変数は利用することができないためコンパイルに失敗する。
実行コード
public static void main(String[] arg){ Object test; System.out.println(test); }
実行結果
java: 変数testは初期化されていない可能性があります
NULLとは
結論からいうとNULLとは、「参照型の参照先が決まっていなかった場合に参照する情報がないということを明示する値」だ。つまりNULLが入った参照型の変数は、値を参照できないし、用意されているメソッドも使うことができない。
Object test = null;
上記の例ではObjectクラスの変数testにNULLが代入されている。ObjectクラスにはString型に変換するtoStringメソッドやハッシュ値を取得するhashCodeメソッドが用意されている。NULLが入った参照型変数のメソッドを使用してみる。その実行コードと実行結果は下記の通り。
実行コード
public static void main(String[] arg){ Object test = null; System.out.println(test.hashCode()); }
実行結果
Exception in thread "main" java.lang.NullPointerException
例外処理、つまりはエラーが発生した。これは「参照する情報がないということが明示的に示されている」にも関わらず参照しようとしたために発生するのだ。
まとめ
NULLとは参照先がないということを明示するために用意されたアドレスであり、javaではその中身を参照することができにようにNullPointerExceptionが用意されている。しかし、これが用意されていないプログラム言語も存在する。C言語が良い例だ。C言語において、どこを参照するか定かではないnullにアクセスすることがご法度とされている。これにより何が起こるかが分からないからだ。皆さんもプログラミングする際は、何をするか分からない処理を実装してしまわないように注意して欲しい。