【Java】Java例外における例外処理

Java例外

コンピュータプログラムを実行する過程では、必ずさまざまなエラーが発生します。

ユーザーによるいくつかの間違いがあります。たとえば、ユーザーはint年齢の種類を入力する必要がありますが、ユーザー入力は次のようになりますabc

// 假设用户输入了abc:
String s = "abc";
int n = Integer.parseInt(s); // NumberFormatException!

プログラムはファイルの内容の読み取りと書き込みを行おうとしていますが、ユーザーがそれを削除しました。

// 用户删除了该文件:
String t = readFile("C:\\abc.txt"); // FileNotFoundException!

ランダムに発生し、決して回避できないエラーもいくつかあります。例えば:

ネットワークが突然切断され、リモート サーバーに接続できなくなる、
メモリが枯渇してプログラムがクラッシュする、
ユーザーが「印刷」をクリックしてもプリンターがまったく表示されない、などの
場合
に、堅牢なプログラムで対処する必要があります。さまざまなエラー。

いわゆるエラーは、プログラムが関数を呼び出すときに発生し、失敗した場合はエラーを意味します。

発信者は通話の失敗に関する情報をどのようにして知るのでしょうか? 次の 2 つの方法があります。

方法 1: エラー コードを返すことに同意します。

たとえば、ファイルを処理する場合、0 が返された場合は成功を意味し、他の整数が返された場合は合意されたエラー コードを意味します。

int code = processFile("C:\\test.txt");
if (code == 0) {
    
    
    // ok:
} else {
    
    
    // error:
    switch (code) {
    
    
    case 1:
        // file not found:
    case 2:
        // no read permission:
    default:
        // unknown error:
    }
}

エラーコードの種類が多いためint、対処が非常に面倒です。このアプローチは、低レベルの C 関数で一般的です。

方法 2: 言語レベルで例外処理メカニズムを提供します。

Java には、常に例外を使用してエラーを示す例外処理メカニズムが組み込まれています。

例外はクラスであるため、それ自体が型情報を持ちます。例外はどこにでもスローできますが、メソッド呼び出しから分離するために上位レベルでのみキャッチする必要があります。

try {
    
    
    String s = processFile(C:\\test.txt”);
    // ok:
} catch (FileNotFoundException e) {
    
    
    // file not found:
} catch (SecurityException e) {
    
    
    // no read permission:
} catch (IOException e) {
    
    
    // io error:
} catch (Exception e) {
    
    
    // other error:
}

Java の例外はクラスであるため、その継承関係は次のようになります。

ここに画像の説明を挿入

それは継承関係からわかります。Throwableそれは異常なシステムの根源であり、それを継承していますObjectと のThrowable2 つのシステムがありこれらは重大なエラーを表します。通常、プログラムは何も行うことができません。次に例を示します。ErrorExceptionError

  • OutOfMemoryError: メモリ不足です
  • NoClassDefFoundError: をロードできませんClass
  • StackOverflowError: スタック オーバーフローは、Exception捕捉して処理できるランタイム エラーです。

特定の例外はアプリケーション ロジック処理の一部であり、捕捉して処理する必要があります。例えば:

  • NumberFormatException: 数値型の形式が間違っています
  • FileNotFoundException: ファイルが見つかりません
  • SocketException: ネットワークの読み取りに失敗しました

不正なプログラム ロジックによって引き起こされる例外もいくつかあり、プログラム自体を修復する必要があります。例えば:

  • NullPointerException: Null オブジェクトのメソッドまたはフィールドの呼び出し
  • IndexOutOfBoundsException: 配列インデックスが範囲外です

例外は次の 2 つのカテゴリに分類されます。

  • RuntimeException とそのサブクラス。
  • 非 RuntimeException (IOException、ReflectiveOperationException などを含む)

Java では次のように規定されています。

Exceptionサブクラスを含めて例外を含めてキャッチする必要がある例外はRuntimeException、このタイプの例外と呼ばれますChecked Exception

キャッチする必要のない例外 (ErrorそのサブクラスRuntimeExceptionとそのサブクラスを含む)。

注: コンパイラは、RuntimeExceptionそのサブクラスに対して必須のキャプチャ要件を設けません。これは、アプリケーション自体が をキャプチャして処理すべきではないという意味ではありませんRuntimeExceptionキャプチャする必要があるかどうかは、特定の問題の具体的な分析によって異なります。

例外をキャッチする

ステートメントを使用して例外をキャッチしtry...catch、その中に例外を引き起こす可能性のあるコードを配置してtry {...}から、catch対応するキャッチExceptionとそのサブクラスを使用します。

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) {
    
    
        try {
    
    
            // 用指定编码转换String为byte[]:
            return s.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
    
    
            // 如果系统不支持GBK编码,会捕获到UnsupportedEncodingException:
            System.out.println(e); // 打印异常信息
            return s.getBytes(); // 尝试使用用默认编码
        }
    }
}

それをキャッチしないとUnsupportedEncodingException、コンパイル失敗の問題が発生します。

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) {
    
    
        return s.getBytes("GBK");
    }
}

コンパイラはエラーを報告します。エラー メッセージは次のようなものでunreported exception UnsupportedEncodingException; must be caught or declared to be thrown、キャプチャする必要があるステートメントがreturn s.getBytes("GBK"); であることが正確に指摘されています。つまり、UnsupportedEncodingExceptionこのようにChecked Exception、捕まえなければなりません。

これは、String.getBytes(String) メソッドの定義が次のようになっているためです。

public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
    
    
    ...
}

メソッドが定義されている場合、throws Xxx を使用して、メソッドがスローする可能性のある例外のタイプを示します。呼び出し時に、呼び出し元はこれらの例外を強制的にキャッチする必要があります。そうしないと、コンパイラがエラーを報告します。

toGBK() メソッドでは、String.getBytes(String)メソッドが呼び出されるため、メソッドをキャプチャする必要がありますUnsupportedEncodingExceptionまた、これをキャプチャすることはできませんが、メソッド定義でこれを使用して、メソッドがnをスローする可能性があるthrowsことを示し、メソッドがコンパイラ チェックに合格できるようにします。toGBK()UnsupportedEncodingExceptiotoGBK()

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
    
    
        return s.getBytes("GBK");
    }
}

上記のコードでもコンパイル エラーが発生しますが、今回は、コンパイラはreturn s.getBytes("GBK");呼び出しの問題をプロンプトしませんが、byte[] bs = toGBK("中文");. main() メソッドでは、呼び出しはtoGBK()スローする可能性のある宣言をキャプチャしないためですUnsupportedEncodingException

修正方法は、例外をキャッチして main() メソッドで処理することです。

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            byte[] bs = toGBK("中文");
            System.out.println(Arrays.toString(bs));
        } catch (UnsupportedEncodingException e) {
    
    
            System.out.println(e);
        }
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
    
    
        // 用指定编码转换String为byte[]:
        return s.getBytes("GBK");
    }
}

メソッドによって宣言されている限りChecked Exception、呼び出しレベルでキャプチャされない場合は、より高い呼び出しレベルでキャプチャする必要があることがわかります。キャッチされなかった例外はすべて最終的にmain()メソッド内でキャッチされる必要があり、try が省略されることはありません。これはコンパイラによって保証されています。この方法は釣れるmain()最後のチャンスでもあります。Exception

テストコードの場合、上記の書き方は少し面倒です。Try コードを書きたくない場合は、次main()のようにメソッドを直接定義できますthrows Exception

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) throws Exception {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
    
    
        // 用指定编码转换String为byte[]:
        return s.getBytes("GBK");
    }
}

main()このメソッドはスローできることを宣言していると同時にException、すべてをスローできることも宣言しているExceptionため、内部でキャプチャする必要はありません。その代償として、例外が発生するとプログラムはすぐに終了します。

内部の異常を「消化」することを好む子供用靴もありますtoGBK()

static byte[] toGBK(String s) {
    
    
    try {
    
    
        return s.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
    
    
        // 什么也不干
    }
    return null;
    ```
这种捕获后不处理的方式是非常不好的,即使真的什么也做不了,也要先把异常记录下来:
```java
static byte[] toGBK(String s) {
    
    
    try {
    
    
        return s.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
    
    
        // 先记下来再说:
        e.printStackTrace();
    }
    return null;

printStackTrace()すべての例外は、例外スタックを出力するメソッドを呼び出すことができます。これは、例外を迅速に出力するためのシンプルで便利なメソッドです。

まとめ

Java は例外を使用してエラーを示し、try ... catch例外をキャッチします。

Java 例外はクラスであり、Throwableそこから継承されます。

Errorこれは、捕捉する必要のない重大なエラーであり、Exception捕捉する必要がある処理可能なエラーです。

RuntimeException必須のキャプチャ、RuntimeException(Checked Exception)必須のキャプチャ、または throws ステートメントはありません。

例外をキャッチして何もしないことはお勧めできません。

おすすめ

転載: blog.csdn.net/ihero/article/details/132148589