どこに行っても、予測不可能な出来事が私たちを待っています。地震、人々の不合理な行動、隕石...またはもっと単純なことでも、電球が切れたり、キャッシュカードが磁力を失ったり、ガソリン計が壊れたりします。予測不可能な出来事を無効にすることはできませんが、少なくとも部分的にはそれらに対して備えることはできます。つまり、それらに対処するための何らかのメカニズムを準備する必要があります。プログラミングの世界、特に Java 言語では、プログラムの正常な動作を妨げるイベントを例外と呼び、プログラムのクラッシュを防ぐメカニズムを例外処理と呼びます。したがって、ゼロ除算などの予期しないイベントがプログラム内で発生した場合、例外を「スロー」する必要があります。例外処理は Java プログラミングの重要な側面であり、開発者がプログラムの実行中に発生する可能性のあるエラーや例外を管理するのに役立ちます。この記事では、例外処理の基本概念の 1 つである Java throwキーワードと、それを使用して例外をスローする方法に焦点を当てます。
Java の例外とは何ですか?
例外とは、プログラムの実行中に発生し、プログラムの命令の通常の流れを中断するイベントです。例外が発生すると、プログラムの実行が停止され、コンソールにエラー メッセージが表示されます。Java には、チェック済み例外とチェックなし例外の 2 種類があります。チェック例外はコンパイル時にチェックされ、コンパイラは呼び出しメソッドによって例外がキャッチまたは宣言されたことを確認します。一方、未チェック例外はコンパイル時にチェックされず、キャッチされることもキャッチされないままになることもあります。以下は、エラーが発生する可能性があるが、コンパイラーがエラーをスキップするコードの例です。public class Factorial {
public static long getFactorial(final int number) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
プログラムの出力は次のとおりです。
1 -4249290049419214848
プログラムは正常に終了しましたが、間違った結果が生成されました。最初のケースでは、関数の引数が負であり、階乗は負の数に対して機能しないためです。2 番目のケースでは、数値が大きすぎて、long 型の範囲で階乗を数えることができないため、結果は間違っています。別の例を次に示します。ある数値を別の数値で割るプログラムを書いてみましょう。
public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
int result = divide(a, b);
System.out.println(result);
}
public static int divide(int a, int b) {
return a / b;
}
}
この例では、変数 b が 0 であるため、 ArithmeticExceptionがスローされます。ただし、このエラーは処理されないため、プログラムは不正なステータスで終了します。
Javaで例外をスローする方法
Java では、例外もオブジェクトであるため、例外は新しい Exception オブジェクトが作成された場合と同様にスローされます。プログラム内で例外をスローするには、 throw ステートメントを使用します。通常、これら 2 つの操作 (オブジェクトの作成と例外のスロー) は 1 つに結合されます。throw new Exception("error…");
Java のthrowキーワードは、プログラムが実行時に処理できないエラーまたは例外条件が発生したときに、メソッドまたはコード ブロックから例外をスローするために使用されます。プログラム フローは最も近い catch ブロックにリダイレクトされます。このブロックは例外を管理できます。
「throw」キーワードの使用例
Java のthrowキーワードの機能を説明するために、例を見てみましょう。数値の階乗を計算するメソッドを書いてみましょう。数値が負の場合は計算できないため、例外をスローする必要があります。同様に、数値が大きすぎる場合、階乗結果がlong型の最大サイズを超え、別の例外がスローされます。ここにメソッドの実装があります。public Class Factorial {
public static long getFactorial(final int number) {
if ((number >= 0) && (number < 21)) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
} else {
//throw new exception here
throw new IllegalArgumentException("THe argument isn't legal");
}
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
この例では、 number の値が負の場合、throwキーワードを使用してIllegalArgumentExceptionクラスのインスタンスをスローします。プログラムを実行すると、「引数が不正です」というメッセージがコンソールに表示されます。プログラムの実行が停止されます。
もうエラーはありません: 例外をキャッチする例
次に、ゼロ除算を使用した 2 番目の例を思い出し、例外処理を使用して実行してみましょう。public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
int result = divide(a, b);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Error: division by zero");
}
}
public static int divide(int a, int b) {
return a / b;
}
}
この例では、ゼロ除算例外を処理するためにtry-catch構造 を追加しました。簡単に言うと、try-catch-finally は、例外が発生したかどうかに関係なく、例外を処理し、コードを実行できるようにする Java プログラミング言語の構造です。 try-catch-finally は3 つのブロックで構成されます。
- tryブロック。潜在的に危険なコードがここで実行されています。それは例外をスローする可能性のあるコードです。tryブロック内で例外が発生した場合、そのブロック内のコードの実行は中止され、制御が catch ブロックに移されます。
- キャッチブロック。ここで、スローされた例外が処理されます。catchブロックでは、キャッチする例外と、キャッチされたときに実行するロジックを指定できます。 いよいよブロック。これは、例外が発生したかどうかに関係なく実行されます。Finallyブロックは、たとえば、try ブロックで割り当てられたリソースを解放する (ファイルやソケットを閉じるなど) ために使用されます。このブロックは省略できます。
キーワードをスローします
throwsキーワードはメソッド シグネチャで使用されます。そうであれば、メソッドで例外がスローされていることを意味します。これにより、呼び出しスタックに例外が伝播され、現在のメソッドで例外を処理する必要がないことが示される場合があります。Java では、「スロー」を使用して、プログラム内で定義されたカスタム例外を参照することもできます。 たとえば、メソッドは 2 つの数値の除算を実行しますが、2 番目の引数がゼロの場合は IllegalArgumentExceptionをスローすることがあります。public static double divide(double a, double b) throws IllegalArgumentException {
if (b == 0) {
throw new IllegalArgumentException("Division by zero is not allowed");
}
return a / b;
}
このメソッドは throws キーワードを使用して、2 番目の引数が null の場合にIllegalArgumentException がスローされる可能性があることを示します。メソッドの実行中にそのような例外が発生した場合、その例外は呼び出し元のメソッドに渡されて処理されます。メソッド呼び出しの例:
public static void main(String[] args) {
double result = 0;
try {
result = divide(10, 0);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("Result: " + result);
}
この例では、divide()メソッドが引数 10 と 0 で呼び出されます。ゼロによる除算は不可能であるため、IllegalArgumentExceptionがスローされます。例外はtry-catchブロックによってキャッチされ、エラー メッセージが表示されます。例外によってdivide()メソッドの実行が終了するため、プログラムの結果はゼロになります。
GO TO FULL VERSION