【Java入門】開発現場でよく発生する例外について原因と対策

スポンサーリンク

こんにちは。いつもブログをご覧いただきありがとうございます。

今回は「開発現場でよく発生する例外について原因と対策」を6つ紹介します。

この6つの例外発生の原因と対策を理解し、良いプログラムコードが書けるようになっていきましょう!

例外発生ベスト6

例外とは、「プログラム実行時に、続行不可の状態になる」ことを指します。

しーま
しーま

ここで取り上げる内容は、実際に開発現場を経験し、よくあるあると感じた内容です。予めご了承くださいm(_ _)m

  • NullPointerException
  • IndexOutOfBoundsException
  • ArrayIndexOutOfBoundsException
  • NumberFormatException
  • ClassCastException
  • ClassNotFoundException

NullPointerException

コンパイル時に見つけられず、実行時にエラーとなる場合が多いですね。

原因

変数などにアクセスする際、参照先が存在しない場合に発生する

実際にプログラムコードを実行して、例外について確認していきましょう!

Personクラスのageフィールドを加算するプログラムです。

public class Main {
    public static void main (String args[] ) {
        Person[] persons = new Person[3];
        int total = 0;
        for ( int i=0; i<persons.length; i++ ) {
            total += persons[i].age;
        }
        System.out.println( total );
    }
}

class Person {
    int age = 18;
}

■プログラム実行結果

Exception in thread “main” java.lang.NullPointerException
at com.company.Main.main(Main.java:8)

【total += persons[i].age;】NullPointerExceptionが発生することを確認できました。

原因は、配列インスタンスを生成しただけで、Personクラス(オブジェクトそのもの)のインスタンスを生成していないからです。

対策

配列のインスタンス生成と同様にオブジェクトのインスタンス生成も行う。

先ほどのプログラムで「オブジェクトのインスタンス生成」を追加します。

public class Main {
    public static void main (String args[] ) {
        Person[] persons = new Person[3];
        int total = 0;
        for ( int i=0; i<persons.length; i++ ) {
            persons[i] = new Person();
            total += persons[i].age;
        }
        System.out.println( total );
    }
}

class Person {
    int age = 18;
}

■プログラム実行結果

54

Personクラスのageフィールドを加算する直前に【persons[i] = new Person();】を記述しました。

そうすることで、Personクラスのフィールドを参照することができました(拍手)

NullPointerExceptionのまとめ

【原因】変数などにアクセスする際、参照先が存在しない場合に発生する

【対策】変数などにアクセスする際、オブジェクトのインスタンスは問題ないか確認する

しーま
しーま

変数がNullかどうか必ずチェックするようにしましょう!

IndexOutOfBoundsException

次は「IndexOutOfBoundsException」です。

原因

確保した要素以上を参照しようとした時に発生する例外

実際にプログラムコードを実行して、例外について確認していきましょう!

import java.util.ArrayList;

public class IndexOutOfBoundsExceptionTest {
  public static void main ( String args[] ) {
    ArrayList<String> list = new ArrayList<String>();
    list.add( "a" );
    list.add( "b" );
    for ( int i = 0; i < 5; i++ ) {
      System.out.println ( list.get(i) );
    }
  }
}

list変数に2つの要素を追加したにも関わらず、8行目のfor文で2以上繰り返し処理を実行しているため、例外が発生してしまいます。

実行結果は以下のようになります。

a
b
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 2

対策

確保した要素の数だけ、処理を行う。

import java.util.ArrayList;

public class IndexOutOfBoundsExceptionTest {
  public static void main ( String args[] ) {
    ArrayList<String> list = new ArrayList<String>();
    list.add( "a" );
    list.add( "b" );
    for (String in : list) {
      System.out.println ( in );
    }
  }
}

例外が発生せず、問題なく実行できていることがわかります。

a
b

ArrayIndexOutOfBoundsException

次は「ArrayIndexOutOfBoundsException」です。

原因

配列の要素外にアクセスした場合に発生する例外

サンプルコードと実行結果

要素数ゼロの配列を作成し、その後、1番目の要素に値を代入するプログラムです。

public class Main {
  public static void main ( String args[] ) {
    String[] array = {};
    array[0] = "Java";
  }
}

java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0

要素数はゼロなので、配列の要素外アクセスとなり例外が発生してしまいます。

対策

宣言した要素の数だけ、処理を行う。

public class Main {
  public static void main ( String args[] ) {
    String[] array = new String[1];
    array[0] = "Java";
    System.out.println( array[0] );
  }
}

配列のインスタンスを生成し、必ず要素数を指定しなければなりません。

Java

NumberFormatException

次は「NumberFormatException」です。

原因

文字列型から数値型に変換する際、変換に失敗した場合に発生する例外

実際にプログラムコードを実行して、例外について確認していきましょう!

public class NumberFormatExceptionTest {
  public static void main(String[] args) {
    String target = "a";
    Integer integer = Integer.parseInt ( target ) ;
    System.out.println(integer);
  }
}

3行目のtarget変数に a という文字列をセットし、4行目にて数値型に変換しようとして、失敗しています。aという文字列は数値ではないですからね。

実行結果は以下のようになります。

Exception in thread "main" java.lang.NumberFormatException: For input string: "a"

対策

変換対象の文字列が数値かどうかチェックを行い、変換処理を行う。

数値チェックを行い、例外を発生させないプログラムコードを実行してみます。

import java.util.regex.Pattern;

public class NumberFormatExceptionTest {
  public static void main(String[] args) {
    String target = "a";
    if ( Pattern.matches("^[0-9]*$", target) ) {
      Integer integer = Integer.parseInt ( target ) ;
      System.out.println(integer);
    } else {
      System.out.println( "not set" );
    }
  }
}

実行結果は以下のようになります。

not set

ClassCastException

次は「ClassCastException」です。

原因

キャストできない型にキャストしようとした時に発生する例外

実際にプログラムコードを実行して、例外について確認していきましょう!

import java.util.ArrayList;
import java.util.List;

public class ClassCastExceptionTest {
  public static void main ( String[] args ) {
    List<Object> list = new ArrayList<Object>();
    list.add("a");
    Integer num = (Integer)list.get(0);
    System.out.println( num );
  }
}

6行目でObject型のlist変数を定義し、7行目で a という文字列をセットしています。

8行目でlist変数の要素を取り出す際に、Integer型としているため、実行時に例外が発生していることがわかります。

実行結果は以下のようになります。

Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer

対策

変換が必要な際は、適切な型に変換する。

import java.util.ArrayList;
import java.util.List;

public class ClassCastExceptionTest {
  public static void main ( String[] args ) {
    List<Object> list = new ArrayList<Object>();
    list.add(100);
    Integer num = (Integer)list.get(0);
    System.out.println( num );
  }
}

8行目において、Integer型で変換を行っているため、例外は発生しません。このように適切な型での変換が必要であることがわかります。

実行結果は以下のようになります。

100

ClassNotFoundException

最後に「ClassNotFoundException」です。

原因

指定した名前のクラス定義が見つからなかった場合に発生する例外

実際にプログラムコードを実行して、例外について確認していきましょう!

public class ClassNotFoundExceptionTest {
  public static void main(String[] args) {
    Class classs;
    try {
      classs = Class.forName( "java.lang.string" );
      System.out.println( classs );
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
}

5行目でClass.forNameメソッドを使用してString型のクラスを取得しようとしています。

実行結果は以下のようになります。

java.lang.ClassNotFoundException: String

対策

Class.forNameメソッドを使用する際に引数は正しく宣言する。

先ほど、引数に「java.lang.string」としましたが、今回は「java.lang.String」とSを大文字にして、プログラムコードを実行してみます。

public class ClassNotFoundExceptionTest {
  public static void main(String[] args) {
    Class classs;
    try {
      classs = Class.forName( "java.lang.String" );
      System.out.println( classs );
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
}

実行結果は以下のようになります。正しくStringクラスが取得できたことを確認できました。

class java.lang.String

さいごに

最後まで読んでいただきありがとうございました。

今回は【Java入門】例外発生の原因と対策について解説を行いました。

いかがだったでしょうか。

おすすめ記事

Javaプログラミングをもう一度本格的に勉強したいっ!」という方へ

逆に、「Javaプログラミング以外を本格的に勉強したいっ!」という方へ

Javaスキルで悩んでいる方必見!本気で学習できる環境を探してみよう!
詳細はこちら
Javaスキルで悩んでいる方必見!本気で学習できる環境を探してみよう!
詳細はこちら
タイトルとURLをコピーしました