エラーの種類 〜プログラムが実行できない場合〜
☆ プログラムが実行できない
・ 「java.lang.NoclassDefFoundError」(その1)
・「java.lang.NoclassDefFoundError」(その2)
原因 何らかの理由で"JVMが指定されたクラスのクラスファイルを見つけられない"
① 起動クラスのクラス名のつづりをタイプミス
② 起動クラスの完全限定クラス名(パッケージつきのクラス名 拡張子はなし)で
指定していない
③ クラスファイルがクラスパス以下のパッケージ階層に対応したフォルダに
配置されてない(保存場所の問題)
④ クラスパスの指定が正しく行われていない(どこにJVMがいくかが分からない)
解決策 ① 起動しようとしているクラス名をタイプミスしていないか確認
ex. Main→mainなどになっていないか
② 起動しようとしているクラスの完全限定クラス名を確認
ex. パッケージ a.b.cのMainクラスを起動
↓
③ クラスファイルが指定の場所に正しく存在するか確認する
特にパッケージに所属するクラスではファイル置き場にも注意が必要
ex. パッケージ a.b.cのMainクラス
(クラスパスのフォルダ「¥a¥b¥c¥Main.class」に
クラスファイルが存在していないといけない)
④ クラスパスが起動時または環境変数で正しく設定しているかを確認
(タイプミスしていないかも確認)
・「java.lang.NoSuchMethodError:Main」(1行目)
原因 起動しようとしたクラスに正しいmainメソッドがない。
mainメソッドを定義したつもりなのにこのメッセージが表示される場合、
細部が間違っている可能性がある
(publicやstaticをつけ忘れている。引数の型が違う。mainのつづりが違う)
解決策 起動しようとしたクラスにmainメソッドが存在することを確認
特にmainメソッドの宣言は一字一句間違っていないことを確認
・「java.lang.ArrayIndexOutOfBoundsException」(1行目)
原因 ある配列について、範囲外の添字を使ってアクセスしようとした
ex 要素3の配列 i [0][1][2]
i[3]やi[-1]にアクセスしようとするとエラー
解決策 エラー報告されている行で、添字が範囲外でないか確認する
(特にforやWhileによるループの中で配列を用いる場合は、ループの回数に注意)
ループにおける範囲外の配列にアクセスするエラーを未然に防ぐためには、
拡張for文を利用する
(拡張for文であれば、範囲内のものだけにしかアクセスしないので)
for(型 任意の変数名:配列要素名)
…配列要素から1つずつ取り出して任意の変数名に代入していく
※なお、エラーメッセージの末尾にあるコロンの右側
エラーメッセージ:3 ←「何番目の要素にアクセスしようとしたか」を示す数字が表示されるので参考にする
・「java.lang.NullPointerException」(1行目)
原因 「nullが格納されている変数(中身が何も入っていない)」に対してフィールドやメソッドを利用しようとした
ex 変数s→null
「s.toString( );」を実行→エラー
ex 「a.method( ).method2( )」のようにメソッドの呼び出しを連ねて記述
(まずaメソッドを実行してから、aメソッドで返ってきた値を元にbメソッドを実行するということ)
→a.method( )の実行結果としてnullが返ってきているので、続けたmethod2( )の呼び出しでエラーが発生している
解決策 エラー報告されている行の中でメソッドやフィールドを利用しようとしている部分(上記のa.method( )の部分)を特定し、
内容がnullでないかを確認する
☆ エラーになる行の直前の変数の内容を画面に出力することで確認出来る
もし出力結果がnullの場合、
ソースコードを逆に遡って「どこでnullになってしまったか」を特定し、修正する
・ 「java.lang.ClassCastException:~cannot be cast to~」
原因
あるインスタンスをそのインスタンスの型または親クラスの型以外へ
キャスト(強制型変換)しようとした場合にこのエラーが発生する
ex. Wizard w=(Wizard) o;
//実際のoの中身はHeroであるにも関わらず、Wizard型へキャストしようとする
※ 多くの場合は、キャストを試みた変数(上記ではo)に何型のインスタンスが入っているかを開発者が理解していないことに起因している
解決策
① キャストを試みた変数(上記の例ではo)にインスタンスを代入されている箇所まで
ソースコードを遡る
② 変数に代入したインスタンスの型(ざっくり捉えて代入した型の前は何の型だったのか)を確認する
③ キャスト(強制型変換したい先)の型を確認。
(代入したい型の中身と代入したい先の型が同じかどうか)
※ 変換先の型がインスタンスの型と同じか、その親クラスの型でなければ、
キャスト(強制型変換)は行うことができない
・ 「java.lang.ArithmeticException:/ by zero」(1行目)
原因 数学的に許されてない「0での割り算」を行った場合
ex int a=b/c; //cの中に0が入っていたのでエラー
※時にユーザーが入力した情報やファイルから読み込んだ情報を割る数として利用した場合に、
入力した値をチェックしていないとこのエラーになりやすい
解決策 どんな条件での動作でも0での除算が行われないようプログラムを修正する