Java - 例外
例外 (または例外イベント) は、プログラムの実行中に発生する問題です。 例外の場合 プログラムの通常の流れが中断され、プログラム/アプリケーションが異常終了することが発生します。これは推奨されません。したがって、これらの例外を処理する必要があります。
例外は、さまざまな理由で発生する可能性があります。以下は、例外が発生するいくつかのシナリオです。
- <リ>
ユーザーが無効なデータを入力しました。
<リ>開く必要のあるファイルが見つかりません。
<リ>通信中にネットワーク接続が失われたか、JVM のメモリが不足しています。
これらの例外には、ユーザー エラーが原因のもの、プログラマー エラーが原因のもの、何らかの形で障害が発生した物理リソースが原因のものがあります。
これらに基づいて、例外の 3 つのカテゴリがあります。 Java で例外処理がどのように機能するかを理解するには、それらを理解する必要があります。
- <リ>
チェック済み例外 − チェック例外は、コンパイル時にコンパイラによってチェック (通知) される例外であり、コンパイル時例外とも呼ばれます。これらの例外は単純に無視することはできません。プログラマはこれらの例外を処理 (処理) する必要があります。
たとえば、FileReader を使用する場合 ファイルからデータを読み取るためのプログラム内のクラス。コンストラクターで指定されたファイルが存在しない場合、FileNotFoundException
例
ライブデモimport java.io.File; import java.io.FileReader; public class FilenotFound_Demo { public static void main(String args[]) { File file = new File("E://file.txt"); FileReader fr = new FileReader(file); } }
上記のプログラムをコンパイルしようとすると、次の例外が発生します。
出力
C:\>javac FilenotFound_Demo.java FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown FileReader fr = new FileReader(file); ^ 1 error
注意 − メソッド read() から および close() の FileReader クラスが IOException をスローすると、コンパイラが FileNotFoundException とともに IOException を処理するように通知することを確認できます。
- <リ>
未チェックの例外 − 非チェック例外とは、実行時に発生する例外です。これらは実行時例外とも呼ばれます .これには、ロジック エラーや API の不適切な使用などのプログラミング バグが含まれます。コンパイル時に実行時例外は無視されます。
たとえば、プログラムでサイズ 5 の配列を宣言していて、6 th を呼び出そうとすると、 配列の要素、次に ArrayIndexOutOfBoundsExceptionexception
例
ライブデモpublic class Unchecked_Demo { public static void main(String args[]) { int num[] = {1, 2, 3, 4}; System.out.println(num[5]); } }
上記のプログラムをコンパイルして実行すると、次の例外が発生します。
出力
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)
- <リ>
エラー - これらはまったく例外ではなく、ユーザーまたはプログラマーの制御を超えて発生する問題です。エラーについてはほとんど何もできないため、通常、コードではエラーは無視されます。たとえば、スタック オーバーフローが発生すると、エラーが発生します。コンパイル時にも無視されます。
例外階層
すべての例外クラスは、java.lang.Exception クラスのサブタイプです。例外クラスは、Throwable クラスのサブクラスです。例外クラス以外に、Throwable クラスから派生した Error という別のサブクラスがあります。
エラーは、重大な障害が発生した場合に発生する異常な状態であり、Java プログラムでは処理されません。エラーは、ランタイム環境によって生成されたエラーを示すために生成されます。例:JVM がメモリ不足です。通常、プログラムはエラーから回復できません。
Exception クラスには、IOException クラスと RuntimeException クラスの 2 つの主要なサブクラスがあります。
以下は、最も一般的なチェック付きおよびチェックなしの Java の組み込み例外のリストです。
例外メソッド
以下は、Throwable クラスで使用できる重要なメソッドのリストです。
Sr.No. | 方法と説明 |
---|---|
1 | public String getMessage() 発生した例外に関する詳細メッセージを返します。このメッセージは、Throwable コンストラクターで初期化されます。 |
2 | public Throwable getCause() Throwable オブジェクトで表される例外の原因を返します。 |
3 | public String toString() getMessage() の結果と連結されたクラスの名前を返します。 |
4 | public void printStackTrace() toString() の結果をスタック トレースと共に System.err、エラー出力ストリームに出力します。 |
5 | public StackTraceElement [] getStackTrace() スタック トレースの各要素を含む配列を返します。インデックス 0 の要素は呼び出しスタックの一番上を表し、配列の最後の要素は呼び出しスタックの一番下にあるメソッドを表します。 |
6 | public Throwable fillInStackTrace() この Throwable オブジェクトのスタック トレースに現在のスタック トレースを入力し、スタック トレース内の以前の情報に追加します。 |
例外のキャッチ
メソッドは try の組み合わせを使用して例外をキャッチします そしてキャッチ キーワード。例外を生成する可能性のあるコードの周りに try/catch ブロックが配置されます。 try/catch ブロック内のコードは保護されたコードと呼ばれ、try/catch を使用するための構文は次のようになります −
構文
try { // Protected code } catch (ExceptionName e1) { // Catch block }
例外が発生しやすいコードは、try ブロックに配置されます。例外が発生すると、発生した例外はそれに関連付けられた catch ブロックによって処理されます。すべての try ブロックの直後に、catch ブロックまたは finally ブロックが続く必要があります。
catch ステートメントには、キャッチしようとしている例外の種類を宣言することが含まれます。保護されたコードで例外が発生した場合、try に続く catch ブロック (またはブロック) がチェックされます。発生した例外のタイプが catch ブロックにリストされている場合、引数がメソッド パラメーターに渡されるのと同じように、例外は catch ブロックに渡されます。
例
以下は、2 つの要素で宣言された配列です。次に、コードは 3 へのアクセスを試みます。 例外をスローする配列の要素。
ライブデモ// File Name : ExcepTest.java import java.io.*; public class ExcepTest { public static void main(String args[]) { try { int a[] = new int[2]; System.out.println("Access element three :" + a[3]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Exception thrown :" + e); } System.out.println("Out of the block"); } }
これにより、次の結果が生成されます-
出力
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 Out of the block
複数のキャッチ ブロック
try ブロックの後に複数の catch ブロックを続けることができます。複数の catch ブロックの構文は次のようになります −
構文
try { // Protected code } catch (ExceptionType1 e1) { // Catch block } catch (ExceptionType2 e2) { // Catch block } catch (ExceptionType3 e3) { // Catch block }
前のステートメントは 3 つの catch ブロックを示していますが、1 回の試行で任意の数のブロックを使用できます。保護されたコードで例外が発生した場合、例外はリストの最初の catch ブロックにスローされます。スローされた例外のデータ型が ExceptionType1 と一致する場合、そこでキャッチされます。そうでない場合、例外は 2 番目の catch ステートメントに渡されます。これは、例外がキャッチされるか、すべてのキャッチで失敗するまで続きます。この場合、現在のメソッドは実行を停止し、例外はコール スタックの前のメソッドにスローされます。
例
これは、複数の try/catch ステートメントを使用する方法を示すコード セグメントです。
try { file = new FileInputStream(fileName); x = (byte) file.read(); } catch (IOException i) { i.printStackTrace(); return -1; } catch (FileNotFoundException f) // Not valid! { f.printStackTrace(); return -1; }
複数のタイプの例外のキャッチ
Java 7 以降、単一の catch ブロックを使用して複数の例外を処理できるようになったため、この機能によりコードが簡素化されます。これがあなたのやり方です −
catch (IOException|FileNotFoundException ex) { logger.log(ex); throw ex;
スロー/スローキーワード
メソッドがチェック済み例外を処理しない場合、メソッドは throws を使用してそれを宣言する必要があります キーワード。 throws キーワードは、メソッドの署名の最後に表示されます。
throw を使用して、新しくインスタンス化された例外またはキャッチした例外のいずれかをスローできます。 キーワード。
スローとスロー キーワード、スローの違いを理解してください。 チェックされた例外の処理を延期し、スローするために使用されます 例外を明示的に呼び出すために使用されます。
次のメソッドは、RemoteException をスローすることを宣言します −
例
import java.io.*; public class className { public void deposit(double amount) throws RemoteException { // Method implementation throw new RemoteException(); } // Remainder of class definition }
メソッドは複数の例外をスローすることを宣言できます。その場合、例外はコンマで区切られたリストで宣言されます。たとえば、次のメソッドは、RemoteException と InsufficientFundsException をスローすることを宣言します −
例
import java.io.*; public class className { public void withdraw(double amount) throws RemoteException, InsufficientFundsException { // Method implementation } // Remainder of class definition }
Finally ブロック
finally ブロックは、try ブロックまたは catch ブロックの後に続きます。コードの finally ブロックは、例外の発生に関係なく常に実行されます。
finally ブロックを使用すると、保護されたコードで何が起こっても、実行したい任意のクリーンアップ タイプのステートメントを実行できます。
finally ブロックは catch ブロックの最後に現れ、次の構文を持ちます −
構文
try { // Protected code } catch (ExceptionType1 e1) { // Catch block } catch (ExceptionType2 e2) { // Catch block } catch (ExceptionType3 e3) { // Catch block }finally { // The finally block always executes. }
例
ライブデモpublic class ExcepTest { public static void main(String args[]) { int a[] = new int[2]; try { System.out.println("Access element three :" + a[3]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Exception thrown :" + e); }finally { a[0] = 6; System.out.println("First element value: " + a[0]); System.out.println("The finally statement is executed"); } } }
これにより、次の結果が生成されます-
出力
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 First element value: 6 The finally statement is executed
次のことに注意してください-
- <リ>
catch 句は、try ステートメントなしでは存在できません。
<リ>try/catch ブロックが存在する場合、finally 句を使用することは必須ではありません。
<リ>try ブロックは、catch 句または finally 句なしでは存在できません。
<リ>try、catch、finally ブロックの間にコードを配置することはできません。
試用リソース
一般に、ストリームや接続などのリソースを使用するときは、finally ブロックを使用して明示的に閉じる必要があります。次のプログラムでは、FileReader を使用してファイルからデータを読み取ります。 そして、finally ブロックを使用して閉じています。
例
import java.io.File; import java.io.FileReader; import java.io.IOException; public class ReadData_Demo { public static void main(String args[]) { FileReader fr = null; try { File file = new File("file.txt"); fr = new FileReader(file); char [] a = new char[50]; fr.read(a); // reads the content to the array for(char c : a) System.out.print(c); // prints the characters one by one } catch (IOException e) { e.printStackTrace(); }finally { try { fr.close(); } catch (IOException ex) { ex.printStackTrace(); } } } }
リソースを試す 、自動リソース管理とも呼ばれます は、Java 7 で導入された新しい例外処理メカニズムであり、try catch ブロック内で使用されるリソースを自動的に閉じます。
このステートメントを使用するには、必要なリソースを括弧内に宣言するだけで、作成されたリソースはブロックの最後で自動的に閉じられます。以下は、try-with-resources ステートメントの構文です。
構文
try(FileReader fr = new FileReader("file path")) { // use the resource } catch () { // body of catch } }
以下は、try-with-resources ステートメントを使用してファイル内のデータを読み取るプログラムです。
例
import java.io.FileReader; import java.io.IOException; public class Try_withDemo { public static void main(String args[]) { try(FileReader fr = new FileReader("E://file.txt")) { char [] a = new char[50]; fr.read(a); // reads the contentto the array for(char c : a) System.out.print(c); // prints the characters one by one } catch (IOException e) { e.printStackTrace(); } } }
try-with-resources ステートメントを使用する際は、次の点に注意してください。
- <リ>
try-with-resources ステートメントでクラスを使用するには、AutoCloseable を実装する必要があります インターフェイスと close() そのメソッドは、実行時に自動的に呼び出されます。
<リ>try-with-resources ステートメントで複数のクラスを宣言できます。
<リ>try-with-resources ステートメントの try ブロックで複数のクラスを宣言している間、これらのクラスは逆の順序で閉じられます。
<リ>括弧内のリソースの宣言を除いて、すべてが通常の try ブロックの try/catch ブロックと同じです。
<リ>try で宣言されたリソースは、try ブロックの開始直前にインスタンス化されます。
<リ>try ブロックで宣言されたリソースは暗黙的に final として宣言されます。
ユーザー定義の例外
Java で独自の例外を作成できます。独自の例外クラスを作成するときは、次の点に注意してください −
- <リ>
すべての例外は、Throwable の子でなければなりません。
<リ>処理ルールまたは宣言ルールによって自動的に実施されるチェック例外を作成する場合は、例外クラスを拡張する必要があります。
<リ>実行時例外を作成する場合は、RuntimeException クラスを拡張する必要があります。
以下のように独自の例外クラスを定義できます −
class MyException extends Exception { }
定義済みの Exception を拡張するだけです クラスを使用して独自の例外を作成します。これらはチェック例外と見なされます。次の InsufficientFundsException class は、Exception クラスを拡張するユーザー定義の例外であり、これをチェック例外にします。例外クラスは、有用なフィールドとメソッドを含む他のクラスと同様です。
例
// File Name InsufficientFundsException.java import java.io.*; public class InsufficientFundsException extends Exception { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } }
ユーザー定義の例外の使用方法を示すために、次の CheckingAccount クラスには、InsufficientFundsException をスローする draw() メソッドが含まれています。
// File Name CheckingAccount.java import java.io.*; public class CheckingAccount { private double balance; private int number; public CheckingAccount(int number) { this.number = number; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) throws InsufficientFundsException { if(amount <= balance) { balance -= amount; }else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } public double getBalance() { return balance; } public int getNumber() { return number; } }
次の BankDemo プログラムは、CheckingAccount の Deposit() メソッドと Withdraw() メソッドの呼び出しを示しています。
// File Name BankDemo.java public class BankDemo { public static void main(String [] args) { CheckingAccount c = new CheckingAccount(101); System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100..."); c.withdraw(100.00); System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); } catch (InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount()); e.printStackTrace(); } } }
上記の 3 つのファイルをすべてコンパイルし、BankDemo を実行します。これにより、次の結果が生成されます-
出力
Depositing $500... Withdrawing $100... Withdrawing $600... Sorry, but you are short $200.0 InsufficientFundsException at CheckingAccount.withdraw(CheckingAccount.java:25) at BankDemo.main(BankDemo.java:13)
一般的な例外
Java では、例外とエラーの 2 つのカテゴリを定義できます。
- <リ>
JVM 例外 - これらは、JVM によって排他的または論理的にスローされる例外/エラーです。例:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException.
<リ>プログラム上の例外 − これらの例外は、アプリケーションまたは API プログラマーによって明示的にスローされます。例:IllegalArgumentException、IllegalStateException。
Java