Java Silver 12.13 switch文に関する問題
switch文の条件式には、プリミティブ型やEnum、String型を戻す式を指定することができます。このとき、nullを戻すとNullPointerExceptionが発生します。これは、switch文の分岐にはハッシュコードが使われるためです。
以下は、設問のコードをコンパイルしたクラスファイルをjavapコマンドで生成した結果の抜粋です。switchがコンパイルされるとこのような中間コードになります。
// ハッシュコード化された文字列
8: lookupswitch {
1567: 36
1598: 48
default: 85
}
この中間コードは、ハッシュコードが1567であれば36行目へ、1598であれば48行目、どちらでもなければ85行目へ飛ぶという意味です。ここで使われている1567や1598という数値がハッシュコードで、それぞれ10や20という文字列を表しています。
// ハッシュコードの確認
Systen.out.println("10".hashCode()); // 1567と表示されるSysten.out.println("20".hashCode()); // 1598と表示される
このようにswitch文でString型を戻す式が使われたときには、まず式の結果のString型オブジェクトのhashCodeメソッドを内部的に呼び出し、その値によって分岐処理を行っているのです。
設問のコードでは、String型のクラス変数strを宣言し(2行目)、その変数の値をswitch文の条件式に与えています(4行目)。しかし、このクラス変数は明示的に初期化されていないため、参照型フィールドのデフォルト値であるnullで暗黙的に初期化されています。
そのため、switch文の実行時にhashCodeメソッドが呼び出されるとNullPointerExceptionが発生します。以上のことから、選択肢Dが正解です。
【3.19, 10.16】