CodeGym /Java Blog /ランダム /Java の例外
John Squirrels
レベル 41
San Francisco

Java の例外

ランダム グループに公開済み
こんにちは!今日のレッスンでは、Java 例外について説明します。日常生活には予期せぬ事態がたくさんあります。たとえば、朝仕事に起きて携帯電話の充電器を探しましたが、どこにも見つかりません。シャワーを浴びるためにバスルームに行くと、配管が凍結していることに気づきました。車に乗り込むが、エンジンがかからない。人間はそのような予期せぬ状況に非常に簡単に対処できます。この記事では、Java プログラムがそれらにどのように対処するかを理解していきます。

Java 例外とは何ですか?

プログラミングの世界では、プログラム実行時のエラーや予期せぬ状況を例外と呼びます。プログラムでは、無効なユーザーの操作、ディスク容量の不足、またはサーバーとのネットワーク接続の切断によって例外が発生することがあります。例外は、プログラミング エラーや API の誤った使用によって発生することもあります。現実世界の人間とは異なり、プログラムはこれらの状況にどのように対処するかを正確に知っている必要があります。このため、Java には例外処理として知られるメカニズムがあります。

キーワードについて一言

Java での例外処理は、プログラム内での次のキーワードの使用に基づいています。
  • try - 例外が発生する可能性のあるコードのブロックを定義します。
  • catch - 例外が処理されるコードのブロックを定義します。
  • finally - オプションのコード ブロックを定義します。存在する場合、try ブロックの結果に関係なく実行されます。
これらのキーワードは、コード内で特別な構造を作成するために使用されます: try{}catchtry{}catch{}finallytry{}finally{}
  • throw - 例外を発生させるために使用されます。
  • throws - メソッドが例外をスローする可能性があることを警告するためにメソッド シグネチャで使用されます。
Java プログラムでのキーワードの使用例:

// This method reads a string from the keyboard

public String input() throws MyException { // Use throws to warn 
// that the method may throw a MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// We use a try block to wrap code that might create an exception. In this case,
// the compiler tells us that the readLine() method in the 
// BufferedReader class might throw an I/O exception
    try {
        s = reader.readLine();
// We use a catch block to wrap the code that handles an IOException  
    } catch (IOException e) {
        System.out.println(e.getMessage());
// We close the read stream in the finally block
    } finally {
// An exception might occur when we close the stream if, for example, the stream was not open, so we wrap the code in a try block
        try {
            reader.close();
// Handle exceptions when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// We've decided that an empty string will prevent our program from working properly. For example, we use the result of this method to call the substring(1, 2) method. Accordingly, we have to interrupt the program by using throw to generate our own MyException exception type.
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

なぜ例外が必要なのでしょうか?

現実世界の例を見てみましょう。高速道路の一部に、耐荷重が限られた小さな橋があると想像してください。橋の限界より重い車が橋の上を通過すると、橋が崩壊する可能性があります。ドライバーにとっての状況は、控えめに言っても例外的なものとなるだろう。これを避けるために、運輸局は何か問題が起こる前に道路に警告標識を設置します。警告標識を見て、ドライバーは自分の車両の重量と橋の最大重量を比較します。車両が重すぎる場合、ドライバーは迂回ルートを選択します。運輸局は、第一に、トラック運転手が必要に応じてルートを変更できるようにし、第二に、幹線道路の危険について運転手に警告し、第三に、一定の条件下では橋を使用してはならないと運転手に警告した。 Java の例外 - 2プログラム内の例外的な状況を防止および解決してプログラムの実行を継続できることが、Java で例外を使用する理由の 1 つです。例外メカニズムを使用すると、入力を検証 (チェック) することで、コード (API) を不正使用から保護することもできます。ここで、あなたが運輸部門であると想像してください。まず、運転手がトラブルに見舞われる可能性がある場所を知る必要があります。次に、警告標識を作成して設置する必要があります。最後に、メインルートで問題が発生した場合は、迂回ルートを提供する必要があります。Java では、例外メカニズムは同様に機能します。開発中、tryブロックを使用してコードの危険なセクションの周囲に「例外バリア」を構築し、catch {}を使用して「バックアップ ルート」を提供します。ブロックを作成し、 finally{}ブロック内に何があっても実行するコードを記述します。「バックアップルート」を提供できない場合、またはユーザーに選択権を与えたい場合は、少なくともユーザーに危険性を警告する必要があります。なぜ?警告標識も何も見ずに、渡れない小さな橋に到達したドライバーの憤りを想像してみてください。プログラミングでは、クラスやメソッドを作成するときに、それらが他の開発者によってどのように使用されるかを常に予測できるわけではありません。その結果、例外的な状況を解決する 100% 正しい方法を予測することはできません。そうは言っても、例外的な状況の可能性について他の人に警告するのは良い方法です。Java の例外メカニズムを使用すると、スローを使用してこれを行うことができます。キーワード — 本質的には、メソッドの一般的な動作に例外のスローが含まれるという宣言です。したがって、このメソッドを使用する人は誰でも、例外を処理するコードを作成する必要があることを知っています。

他人に「トラブル」について警告する

メソッド内で例外を処理する予定はないが、例外が発生する可能性があることを他のユーザーに警告したい場合は、throwsキーワードを使用します。メソッド シグネチャ内のこのキーワードは、特定の条件下でメソッドが例外をスローする可能性があることを意味します。この警告はメソッド インターフェイスの一部であり、ユーザーは独自の例外処理ロジックを実装できます。スローの後に、スローされる例外のタイプを指定します。これらは通常、Java のExceptionクラスから派生したものです。Java はオブジェクト指向言語であるため、すべての例外は Java のオブジェクトです。 Java の例外 - 3

例外階層

プログラムの実行中にエラーが発生すると、JVM は Java 例外階層 (共通の祖先から派生する可能性のある例外のセット) である Throwable クラスから適切なタイプのオブジェクトを作成します。例外的な実行時の状況は、次の 2 つのグループに分類できます。
  1. プログラムが回復できず、通常の動作を継続できない状況。
  2. 回復が可能な状況。
最初のグループには、 Errorクラスから派生した例外が関係する状況が含まれます。これらは、JVM の誤動作、メモリ オーバーフロー、またはシステム障害によって発生するエラーです。これらは通常、ソフトウェアでは解決できない重大な問題を示しています。Java では、このような例外の可能性はコンパイラによってチェックされないため、未チェック例外として知られています。このグループには、 Exceptionから派生した例外である RuntimeExceptions も含まれます。クラスに含まれており、実行時に JVM によって生成されます。多くの場合、これらはプログラミング エラーによって引き起こされます。これらの例外はコンパイル時にチェックされない (未チェック) ため、それらを処理するコードを作成する必要はありません。2 番目のグループには、プログラムを作成するときに予見できる例外的な状況が含まれます (したがって、それらを処理するコードを作成する必要があります)。このような例外はチェック例外と呼ばれます。例外に関して言えば、Java 開発者の仕事のほとんどは、そのような状況を処理することです。

例外の作成

プログラムが実行されると、JVM によって、またはthrowステートメントを使用して手動で例外が生成されます。これが発生すると、例外オブジェクトがメモリ内に作成され、プログラムのメイン フローが中断され、JVM の例外ハンドラが例外を処理しようとします。

例外処理

Java では、 try{}catchtry{}catch{}finally、およびtry{}finally{}コンストラクト を使用して、例外処理の必要性が予想されるコード ブロックを作成します。tryJava の例外 - 4ブロックで例外がスローされると、JVM は次のcatchブロックで適切な例外ハンドラーを探します。catchブロックに必要な例外ハンドラーがある場合、制御はそれに渡されます。そうでない場合、JVM は適切なハンドラーが見つかるまで、catchブロックのチェーンをさらに調べます。catchブロックを実行した後、制御はオプションのfinallyブロックに移ります。適当なキャッチならブロックが見つからない場合、JVM はプログラムを停止し、finallyブロックが存在する場合は最初にそれを実行した後、スタック トレース(メソッド呼び出しの現在のスタック)を表示します。例外処理の例:

public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside print method: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s : list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
    }
mainメソッド の結果は次のとおりです。

Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------
通常、 finallyストリームを閉じ、tryブロック内で開かれた/割り当てられたリソースを解放するために使用されます。ただし、プログラムを作成するときに、すべてのリソースの終了を常に追跡できるとは限りません。私たちの作業を楽にするために、Java の開発者は、tryブロック内で開かれたリソースを自動的に閉じるtry-with-resources構造を提供しています。最初の例は、 try-with-resourcesを使用して書き直すことができます。

public String input() throws MyException {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")) {
        throw new MyException ("The string cannot be empty!");
    }
    return s;
}
バージョン 7 で導入された Java 機能のおかげで、異種例外のキャッチを 1 つのブロックに結合して、コードをよりコンパクトで読みやすくすることもできます。例:

public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

結論

Java で例外を使用すると、「バックアップ ルート」を作成してプログラムをより堅牢にし、catch ブロックを使用してメイン コードを例外処理コードから分離し、throw を使用して例外処理の責任をメソッドの使用者に移すことができます
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION