Java try と catch の使用法
Java ランタイム システムによって提供されるデフォルトの例外ハンドラーはデバッグに役立ちますが、通常は例外を自分で処理する必要があります。これには 2 つの利点があります。まず、エラーを修正できるようになります。 2 番目に、プログラムが自動的に終了するのを防ぎます。ほとんどのユーザーは、プログラムの終了時やエラーが発生するたびにスタック トレースが出力されることに (控えめに言っても) イライラします。幸いなことに、これは簡単に回避できます。
ランタイムエラーを防止して処理するには、監視したいコードを try ブロックに入れるだけです。 try ブロックの直後に、キャッチするエラーの種類を指定する catch 句を含めます。このタスクを実行するのは簡単です。次のプログラムには、ゼロによる除算によって発生する ArithmeticException 例外を処理する try ブロックと catch 句が含まれています。
class Exc2 { public static void main(String args[]) { int d, a; try { // monitor a block of code. d = 0; a = 42 / d; System.out.println("This will not be printed."); } catch (ArithmeticException e) { // catch divide-by-zero error System.out.println("Division by zero."); } System.out.println("After catch statement."); } }
プログラムの出力は次のとおりです:
Division by zero. After catch statement.
try ブロック内の println() の呼び出しは決して実行されないことに注意してください。例外が発生すると、プログラム制御は try ブロックから catch ブロックに移されます。実行が catch ブロックから try ブロックに「戻る」ことはありません。したがって、「これは印刷されません。」は表示されません。 catch ステートメントが実行されると、プログラム制御は try/catch メカニズム全体の下の行から続行されます。
try とその catch ステートメントは 1 つの単位を形成します。 catch 句のスコープは、try ステートメントの前に定義されたステートメントに限定されます。 catch ステートメントは、別の try ステートメントによって発生した例外をキャッチできません (ネストされた try ステートメントの場合を除く)。
try で保護されたステートメント宣言は中括弧内になければなりません (つまり、ブロック内になければなりません)。 try を単独で使用することはできません。
catch 句を構築する目的は、例外を解決し、エラーが発生しなかったかのように実行を継続することです。たとえば、次のプログラムでは、for ループの各反復で 2 つのランダムな整数が生成されます。これら 2 つの整数を互いに除算し、その結果を使用して 12345 を除算します。最終結果は a に保存されます。除算演算の結果としてゼロ除算エラーが発生した場合、それが捕捉され、a の値がゼロに設定され、プログラムが続行されます。
// Handle an exception and move on. import java.util.Random; class HandleError { public static void main(String args[]) { int a=0, b=0, c=0; Random r = new Random(); for(int i=0; i<32000; i++) { try { b = r.nextInt(); c = r.nextInt(); a = 12345 / (b/c); } catch (ArithmeticException e) { System.out.println("Division by zero."); a = 0; // set a to zero and continue } System.out.println("a: " + a); } } }
例外の説明を表示する
Throwable は toString() メソッド (Object によって定義される) をオーバーロードするため、例外の説明を含む文字列を返します。例外を println() のパラメータに渡すことで、例外の説明を表示できます。たとえば、前のプログラムの catch ブロックは
catch (ArithmeticException e) { System.out.println("Exception: " + e); a = 0; // set a to zero and continue }
として書き換えることができます。このバージョンが元のプログラムのバージョンに置き換えられ、プログラムが標準の javaJDK インタプリタで実行されると、ゼロ除算エラーが発生するたびに次のメッセージが表示されます。次のメッセージ:
Exception: java.lang.ArithmeticException: / by zero
コンテキストにもかかわらず、 には特別な値はありません。例外の説明を表示する機能は、他の状況、特に例外を実験およびデバッグしている場合に役立ちます。
Java の複数の catch ステートメントの使用
場合によっては、単一のコード セグメントによって複数の例外が発生する可能性があります。この状況に対処するには、それぞれが例外の種類をキャッチする 2 つ以上の catch 句を定義できます。例外が発生すると、各 catch 句が順番にチェックされ、例外の種類に一致する最初の句が実行されます。 catch ステートメントが実行されると、他の句はバイパスされ、try/catch ブロックの後のコードから実行が続行されます。次の例は、2 つの異なる例外タイプを使用して設計されています:// Demonstrate multiple catch statements. class MultiCatch { public static void main(String args[]) { try { int a = args.length; System.out.println("a = " + a); int b = 42 / a; int c[] = { 1 }; c[42] = 99; } catch(ArithmeticException e) { System.out.println("Divide by 0: " + e); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Array index oob: " + e); } System.out.println("After try/catch blocks."); } }
以下は 2 つの異なる状況で実行されるプログラムの出力です:
C:\>java MultiCatch a = 0 Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks. C:\>java MultiCatch TestArg a = 1 Array index oob: java.lang.ArrayIndexOutOfBoundsException After try/catch blocks.
複数の catch ステートメントを使用する場合、例外サブクラスはその親クラスよりも前に使用する必要があることに留意することが重要です。これは、親クラスの catch ステートメントを使用すると、この型とそのすべてのサブクラスの例外がキャッチされるためです。このようにすると、子クラスが親クラスより遅れている場合、子クラスは決して到着しません。さらに、Java の到達不能なコードはバグです。たとえば、次のプログラムについて考えてみましょう:
/* This program contains an error. A subclass must come before its superclass in a series of catch statements. If not,unreachable code will be created and acompile-time error will result. */ class SuperSubCatch { public static void main(String args[]) { try { int a = 0; int b = 42 / a; } catch(Exception e) { System.out.println("Generic Exception catch."); } /* This catch is never reached because ArithmeticException is a subclass of Exception. */ catch(ArithmeticException e) { // ERROR - unreachable System.out.println("This is never reached."); } } }
このプログラムをコンパイルしようとすると、例外がすでにキャッチされているため 2 番目の catch ステートメントに到達できないことを示すエラー メッセージが表示されます。 ArithmeticException は Exception のサブクラスであるため、最初の catch ステートメントは、ArithmeticException を含むすべての Exception 指向のエラーを処理します。これは、2 番目の catch ステートメントが実行されないことを意味します。プログラムを変更するには、2 つの catch ステートメントの順序を逆にします。
Java での例外処理のための try および catch コード ブロックの使用に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。