English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 基礎教程

Java フローコントロール

Java 配列

Java 面向オブジェクト(I)

Java 面向オブジェクト(II)

Java 面向オブジェクト(III)

Java 異常処理

Java リスト(List)

Java キュー(キュー)

Java Map 集合

Java Set 集合

Java 入出(I/O)

Java Reader/Writer

Javaの他のトピック

Java 異常処理

このチュートリアルでは、Javaを使用して例外を処理する方法について学びます。例外を処理するために、try ... catch ... finallyブロックを使用します。

前のチュートリアルでは、例外について学びました。例外はプログラムの実行中に発生する予期せぬイベントです。

例外の捕捉と処理

Javaでは、try、catch、finallyブロックを使用する例外処理コンポーネントを使用して例外を処理します。

例外をキャッチして処理するために、try...catch...finallyコードブロックを例外を生成する可能性のあるコードの周りに配置します。finallyブロックは任意です。

try...catch...finallyの構文は:

try {
  // コード
catch (ExceptionType e) { 
  // キャッチブロック
} finally {
  //finallyブロック
}

Java try ... catchブロック

例外を生成する可能性のあるコードはtryブロック内に配置されます。

各tryブロックの後には、catchまたはfinallyブロックがすぐに続くべきです。例外が発生した場合、その後に続くcatchブロックでキャッチされます。

 catchブロックは単独では使用できません。tryブロックのすぐ後に配置する必要があります。

例1:try ... catchブロック

class Main {
  public static void main(String[] args) {
    try {
      int divideByZero = 5 / 0;
      System.out.println("tryブロック内の残りのコード");
    } catch (ArithmeticException e) {
      System.out.println("ArithmeticException => "); + e.getMessage());
    }
  }
}

出力結果

ArithmeticException => / by zero

この例では

  • tryブロック内で数字を0で割ります。これによりArithmeticExceptionが発生します。

  • 例外が発生した場合、プログラムはtryブロック内の残りのコードをスキップします。

  • ここでは、ArithmeticExceptionを処理するためのcatchブロックを作成しました。したがって、catch実行ブロック内のステートメントを実行します。

tryブロック内の全てのステートメントが例外を生成しない場合、catchコードブロックはスキップされます。

複数のキャッチブロック

各tryブロックには、0個または複数のcatchブロックがあります。

各キャッチブロックの引数のタイプは、処理できる例外のタイプを示します。複数のキャッチブロックを使用することで、各例外に対して異なる方法で処理できます。

例2:複数のキャッチブロック

class ListOfNumbers {
  public int[] arrayOfNumbers = new int[10];
  public void writeList() {
    try {
      arrayOfNumbers[10} 11;
    catch (NumberFormatException e1) {
      System.out.println("NumberFormatException => " + e1.getMessage());
    } catch (IndexOutOfBoundsException e2) {
      System.out.println("IndexOutOfBoundsException => " + e2.getMessage());
    }
  }
}
class Main {
  public static void main(String[] args) {
    ListOfNumbers list = new ListOfNumbers();
    list.writeList();
  }
}

出力結果

IndexOutOfBoundsException => Index 10 長さの範囲外 10

この例では、サイズが10 の整数配列arrayOfNumbers。

私たちは配列のインデックスは常に0から始まることを知っています。したがって、インデックス10値を割り当てる際にIndexOutOfBoundsExceptionが発生します。なぜなら、arrayOfNumbers配列の境界は0からです。9。

tryブロックで例外が発生した場合、

  • 例外が最初のcatchブロックに投げられます。最初のcatchブロックはIndexOutOfBoundsExceptionを処理しませんので、次のcatchブロックに渡されます。

  • 上記の例の第2つのcatchブロックは適切な例外処理プログラムであり、それがIndexOutOfBoundsExceptionを処理するため、実行されます。

JavaのFinallyブロック

それぞれのtryブロックに対して、finallyブロックは1つのみです。

finallyブロックは任意です。ただし、定義されている場合、常に実行されます(例外が発生しない場合でも)。

例外が発生した場合、try...catchブロックの後に実行されます。例外が発生しない場合、tryブロックの後に実行されます。

finallyブロックの基本的な構文は以下の通りです:

try {
  //code
} catch (ExceptionType1 e1) { 
  // catch ブロック
} catch (ExceptionType1 e2) {
 // catch ブロック
} finally {
  //finallyブロックは常に実行されます
}

例3:finallyブロックの例

class Main {
  public static void main(String[] args) {
    try {
      int divideByZero = 5 / 0;
    } catch (ArithmeticException e) {
      System.out.println("ArithmeticException => "); + e.getMessage());
    } finally {
      System.out.println("Finallyブロックは常に実行されます");
    }
  }
}

出力結果

ArithmeticException => / by zero
finallyブロックは常に実行されます

この例では、0で割ることを試みます。これはArithmeticExceptionがcatchブロックでキャッチされ、finallyブロックは常に実行されます。

finallyブロックを使用することは良い慣習とされています。それは重要なクリーンアップコードを含んでいるからです。

  • return、continueまたはbreak文によって意図せずスキップされる可能性のあるコード

  • ファイルや接続を閉じます

私たちは言及しましたが、finallyは常に実行されますが、ある場合にはfinallyブロックが実行されません:

  • System.exit()メソッドを使用して

  • finallyブロックで例外が発生しました

  • スレッドが終了されました

例4:try、catchおよびfinallyの例

以下は例を示します。FileWriterを使用して新しいファイルを作成し、PrintWriterを使用してデータを書き込もうと試みます。

import java.io.*;
class ListOfNumbers {
  private int[] list = new int[10];
  public ListOfNumbers() {
    //リストの配列に整数値を格納します
    for (int i = 0; i < 10; i++) {
      list[i] = i;
    } 	
  }
}
  public void writeList() {
    PrintWriter out = null;
    try {
      System.out.println("try文に進入します");
      //新しいファイルOutputFile.txtを作成します
      out = new PrintWriter(new FileWriter("OutputFile.txt"));
      //リストの配列の値を新しく作成したファイルに書き込みます
      for (int i = 0; i < 10; i++) {
        out.println("Value at: " + i + " = " + list[i]);
      }
    } catch (IndexOutOfBoundsException e1) {
      System.out.println("IndexOutOfBoundsException => " + e1.getMessage());
    } catch (IOException e2) {
      System.out.println("IOException => " + e2.getMessage());
    } finally {
      //PrintWriterが開かれているか確認します
      if (out != null) {
        System.out.println("PrintWriterを閉じます");
        out.close();
      } else {
        System.out.println("PrintWriterを開くことができません");
      }
    }
  }
}
class Main {
  public static void main(String[] args) {
    ListOfNumbers list = new ListOfNumbers();
    list.writeList();
  }
}

このプログラムを実行するときは、2つの可能性があります:

  1. tryブロック内で異常が発生します

  2. tryブロックが正常に実行されます

新しいFileWriterを作成する際に異常が発生する可能性があります。指定されたファイルを作成または書き込むことができなかった場合、IOExceptionがスローされます。

異常が発生した場合、以下の出力を得ることができます。

try文に入る
IOException => OutputFile.txt
PrintWriterをオープンできません

例外が発生しない場合で、tryブロックが通常通り実行される場合、以下の出力が得られます。

try文に入る
PrintWriterを閉じる

OutputFile.txtが作成され、以下の内容を含みます

Value at: 0 = 0
Value at: 1 = 1
Value at: 2 = 2
Value at: 3 = 3
Value at: 4 = 4
Value at: 5 = 5
Value at: 6 = 6
Value at: 7 = 7
Value at: 8 = 8
Value at: 9 = 9

try ... catch...finallyの詳細なフロー

これらの例を助けに、例外処理のフローを詳細に理解してみましょう。

上の図は、新しいFileWriterを作成中に例外が発生した場合のプログラムの実行フローを示しています。

  • 発生した例外のメソッドを見つけるために、メインメソッドがwriteList()メソッドを呼び出し、それがFileWriter()メソッドを呼び出して新しいOutputFile.txtファイルを作成します。

  • 例外が発生した場合、実行時システムはtryブロック内の残りのコードをスキップします。

  • システムは逆の順序で呼び出しスタックを検索し、適切な例外処理プログラムを見つけます。

  • ここでは、FileWriterには例外処理プログラムがありません。したがって、実行時システムは呼び出しスタックの次のメソッド、つまりwriteListをチェックします。

  • writeListメソッドには、IndexOutOfBoundsExceptionを処理する1つの例外処理プログラムとIOExceptionを処理する別の例外処理プログラムがあります。

  • その後、システムはこれらの処理プログラムを順次処理します。

  • この例では、最初の処理プログラムはIndexOutOfBoundsExceptionを処理します。これはtryブロックで生成されたIOExceptionと一致しません。

  • したがって、次の処理プログラムが哪个IOException処理プログラムであるかを確認します。例外の種類が一致する場合、対応するcatchブロック内のコードが実行されます。

  • 例外処理プログラムの実行後、finallyブロックが実行されます。

  • このシナリオでは、FileWriterで例外が発生したため、PrintWriterオブジェクトのoutがオープンされず、閉じる必要はありません。

今、このプログラムを実行中に例外が発生しないと仮定して、tryブロックが通常通り実行される場合を考えてみましょう。この場合、OutputFile.txtが作成され、書き込まれます。

よく知られているように、finallyブロックの実行は例外処理に関連していません。例外が発生しないため、PrintWriterがオープンされ、閉じる必要があります。これはfinallyブロック内のout.close()ステートメントで行われます。

複数の例外をキャッチ

Java SEから 7より高いバージョンから、現在は一つのcatchブロックで複数の例外の種類をキャッチすることができます。

これにより、コードの重複を減らし、シンプルさと効率を向上させることができます。

catchブロックで処理できるすべての例外の種類は、竖線(|)で区切ります。

その構文は以下の通りです:

try {
  // code
} catch (ExceptionType1 | Exceptiontype2 ex) { 
  // catchブロック
}

さらに詳しい情報を取得するには、以下のURLにアクセスしてください。Javaが複数の例外をキャッチ

try-with-resources文

try-with-resources文は、一つまたは複数のリソース宣言を持つtry文です。

その構文は以下の通りです:

try (resource declaration) {
  // リソースの使用
} catch (ExceptionType e1) {
  // catchブロック
}

リソースはプログラム終了時に閉じる必要があるオブジェクトです。try文内で宣言および初期化する必要があります。

例を示しましょう。

try (PrintWriter out = new PrintWriter(new FileWriter("OutputFile.txt"))) {
  // リソースの使用
}

try-with-resources文はまた自動リソース管理

さらに詳しい情報を取得するには、以下のURLにアクセスしてください。Java try-with-resources文