本章では、Javaのプログラムを動作させた際、エラーが発生した時に表示されるメッセージの読み方とその解消方法について学習します。
プログラムが動作する際に、予期しない状態が発生した時に表示されるメッセージのことです。
エラーメッセージには、誤りの発生箇所や種類、内容などが表示されているので、エラーメッセージを正しく読み取ることはエラーや不具合の解消のためにとても必要なことです。
ここでは、簡単なプログラムを通して、エラーメッセージの読み方とその解消方法を学んでいきましょう。
なお、エラーメッセージの内容は、Javaのバージョンによって異なります。
この章で表示されるエラーメッセージはJava17の内容となっています。
以下のサンプルプログラムを実装して、実行してみましょう。
「jp.techfun」パッケージに、以下のプログラムを作成してください。
package jp.techfun;
public class ErrorMessageSample01 {
public static void main(String[] args) {
String str = null;
int converted = Integer.parseInt(str);
System.out.println("int型変換後の値は " + converted + " です。");
}
}
上記で作成したプログラムを実行すると、以下のようなメッセージがコンソールに出力されます。
Exception in thread "main" java.lang.NumberFormatException: Cannot parse null string
at java.base/java.lang.Integer.parseInt(Integer.java:630)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at jp.techfun.ErrorMessageSample01.main(ErrorMessageSample01.java:8)
それでは、エラー情報を確認していきましょう。
以下のステップに従って読んでいきます。
Eclipseのコンソールには収まりきらないメッセージが表示されている場合があります。
まずは、スクロールバーを上下左右に動かして、エラーメッセージ全体を確認しましょう。
この時点では、内容が理解できなくても構いません。
上下左右にスクロールバーを動かして、どのくらいの分量があるのか、プログラムの修正前後で内容が変わったかなど、くまなく目を通してください。
次に、エラーの種類を特定するために必要な情報として、「~~Exception」という文字を探してください。
今回のサンプルプログラム「ErrorMessageSample01.java」の場合は、以下の図のように「NumberFormatException」を見つけることができます。
「NumberFormatException」は、文字列を数値に変換しようとしたが、うまく変換できなかったときに発生します。
そして、その隣にエラーの原因が書かれており、今回は「Cannot parse null string」と書かれていることから、「String型のnullを変換できなかった」ことが分かります。
JavaのプログラムにおいてExceptionの種類は様々ありますが、代表的なものとしては以下のようなものがあります。
次に、エラーの発生箇所を特定するための情報として、自分が作成したクラス名や変数名などを探してください。
クラス名やファイル名の末尾に数字が付与されている場合は、その数字は行番号を表します。
今回のサンプルプログラムの場合は、以下の情報を見つけることができます。
at jp.techfun.ErrorMessageSample01.main(ErrorMessageSample01.java:8)
コンソールだと、下記の画像の位置に出力されています。
よって、jp.techfunパッケージにあるErrorMessageSample01クラスのmainメソッド(ErrorMessageSample01クラスの8行目)でエラーが発生したことが読み取れます。
ErrorMessageSample01クラスの8行目でString変数「str」をint型に変換しようとしていますが、nullだったため、int型への変換が正しく変換出来ませんでした。
その結果NumberFormatExceptionが発生しました。
それでは、エラー原因が分かったため、エラーを解消していきましょう。
変数「str」がnullだったためにint型への変換が正しく変換ができなかったので、それを解消するために以下のような修正を行うことにします。
package jp.techfun;
public class ErrorMessageSample01 {
public static void main(String[] args) {
String str = "10"; // 【修正箇所】変数「str」へ代入する文字列を変更する。
int converted = Integer.parseInt(str);
System.out.println("int型変換後の値は " + converted + " です。");
}
}
これで、正しくint型への変換が行われるようになりました。
続いて、複数のクラスをまたいでエラーが発生するパターンを見てみましょう。
以下のサンプルプログラムを実装して、実行して下さい。
「jp.techfun」パッケージに、以下のプログラムを作成してください。
package jp.techfun;
public class ErrorMessageSample02 {
public static void main(String[] args) {
Calc calc = new Calc();
System.out.println(calc.add(null, 2));
}
}
package jp.techfun;
public class Calc {
// 2つの引数の和を返す
public int add(Integer a, Integer b) {
return a + b;
}
}
上記で作成したプログラムを実行すると、以下のようなメッセージがコンソールに出力されます。
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "a" is null
at jp.techfun.Calc.add(Calc.java:7)
at jp.techfun.ErrorMessageSample02.main(ErrorMessageSample02.java:8)
1つのクラス内で発生したエラー情報の確認と同様に、エラーメッセージを確認していきましょう。
繰り返しになりますが、スクロールバーを動かして、上下左右くまなく目を通してください。
どのくらいの分量があるのか、一度見たことがあるエラーと似ているのか、エラーの内容に前回と変わった箇所はあるのかなどを確認しましょう。
今回の場合は、以下の図のように「NullPointerException」が見つかりました。
そして、発生原因として「Cannot invoke “java.lang.Integer.intValue()” because “a” is
null」とあることから、「変数aがnullだったため、java.lang.Integer.intValue()の実行ができなかった(=int型への変換ができなかった)」ということが分かります。
今回のサンプルプログラムの場合は、以下の情報を見つけることができます。
at jp.techfun.Calc.add(Calc.java:7)
at jp.techfun.ErrorMessageSample02.main(ErrorMessageSample02.java:8)
コンソールだと、下記の画像の位置に出力されています。
クラス名が2つ見つかりました。
エラーメッセージは、一番上にエラーの発生箇所が出力され、下に向かって呼び出し元に戻るように出力されます。
よって、エラーの発生箇所はjp.techfunパッケージにあるCalcクラスのaddメソッド(Calcクラスの7行目)ですが、その呼び出し元はjp.techfunパッケージにあるErrorMessageSample02クラスのmainメソッド(ErrorMessageSample02クラスの8行目)となります。
Calcクラスの7行目でint型の変数の加算を行っていますが、呼び出し元では、引数aにnullを渡しています。
そのため、nullとの加算ができずにNullPointerExceptionが発生しました。
それでは、エラーを解消してきましょう。
正しく加算を行うために、ErrorMessageSample02.javaに以下のような修正を行います。
package jp.techfun;
public class ErrorMessageSample02 {
public static void main(String[] args) {
Calc calc = new Calc();
System.out.println(calc.add(5, 2)); // 【修正箇所】null以外の値をセットする。
}
}
これで、正しく加算できるようになりました。
確認したエラー情報から、「どのようなException」が発生しているかが分かりました。
そして、「どのパッケージの」「どのクラスの」「何行目で」発生したのか、「どのような原因で」発生したのかも分かりました。
エラーの解消にはいろいろな方法がありますが、その都度仕様と照らし合わせ、仕様を満たす適切な方法でエラーの解消を行ってください。
例えば、サンプルプログラム「ErrorMessageSample01.java」の場合は、String変数「str」にnull以外の値を代入することでエラーを解消しましたが、そのほかにも、以下のような対応方法が考えられます。
なお、エラーを解消するにあたり、発生した各Exceptionがどのような時に発生し、どのような意味を持っているのかが分からない場合は、 JavaのAPIドキュメントで調べるようにしましょう。
Javaのエラーメッセージの読み方とその解消方法についての説明は、以上です。
エラーメッセージを丁寧に読み解き、その都度様々な対応策を考え、実施していきましょう。