Javaでこういうコードを書きました(簡略化してます)
public Boolean getWrapper()
{
return null;
}
public boolean getPrimitive()
{
return getWrapper();
}
public static void main()
{
System.out.println(getPrimitive());
}
これを実行すると、java.lang.NullPointerException
で落ちます。ですがスタックトレースを辿ると例外が吐かれているのは
return getWrapper();
の行でした。ということは、Boolean
型からboolean
型への暗黙的な変換時に例外は発生しているんですが、それならjava.lang.ClassCastException
じゃないのかなーとか思ったりして原因を調べてみました
Java5~は自動ボクシングという機能でプリミティブ型とラッパークラスが暗黙的に変換されるようになっています
Boolean b1 = true; //代入できる
boolean b2 = b1; //代入できる
が、これはコーディング時だけのことで、コンパイルされると
Boolean b1 = Boolean.valueOf(true);
boolean b2 = b1.booleanValue();
と変換されます。つまり型変換時にインスタンスメソッドを呼んでます。
なので最初のコードはコンパイラによって
public Boolean getWrapper()
{
return null;
}
public boolean getPrimitive()
{
return getWrapper().booleanValue();
}
public static void main()
{
System.out.println(getPrimitive());
}
となるので、nullにbooleanValue()
を呼び出してしまって、発生する例外はjava.lang.NullPointerException
だったというわけです。
IDEでデバッグすると、何もインスタンスメンバを呼び出してないのにぬるぽされてしまって戸惑いましたが、実行時のコードを意識すると納得できた、という話でした。