English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
このチュートリアルでは、Javaを使用して例外を処理する方法について学びます。例外を処理するために、try ... catch ... finallyブロックを使用します。
前のチュートリアルでは、例外について学びました。例外はプログラムの実行中に発生する予期せぬイベントです。
Javaでは、try、catch、finallyブロックを使用する例外処理コンポーネントを使用して例外を処理します。
例外をキャッチして処理するために、try...catch...finallyコードブロックを例外を生成する可能性のあるコードの周りに配置します。finallyブロックは任意です。
try...catch...finallyの構文は:
try { // コード catch (ExceptionType e) { // キャッチブロック } finally { //finallyブロック }
例外を生成する可能性のあるコードはtryブロック内に配置されます。
各tryブロックの後には、catchまたはfinallyブロックがすぐに続くべきです。例外が発生した場合、その後に続くcatchブロックでキャッチされます。
catchブロックは単独では使用できません。tryブロックのすぐ後に配置する必要があります。
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ブロックがあります。
各キャッチブロックの引数のタイプは、処理できる例外のタイプを示します。複数のキャッチブロックを使用することで、各例外に対して異なる方法で処理できます。
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を処理するため、実行されます。
それぞれのtryブロックに対して、finallyブロックは1つのみです。
finallyブロックは任意です。ただし、定義されている場合、常に実行されます(例外が発生しない場合でも)。
例外が発生した場合、try...catchブロックの後に実行されます。例外が発生しない場合、tryブロックの後に実行されます。
finallyブロックの基本的な構文は以下の通りです:
try { //code } catch (ExceptionType1 e1) { // catch ブロック } catch (ExceptionType1 e2) { // catch ブロック } finally { //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ブロックで例外が発生しました
スレッドが終了されました
以下は例を示します。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つの可能性があります:
tryブロック内で異常が発生します
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
これらの例を助けに、例外処理のフローを詳細に理解してみましょう。
上の図は、新しい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文です。
その構文は以下の通りです:
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文。