1. 例外の概要
1.1 プログラム例外とは
コンピューター言語を使用したプロジェクト開発の過程で、プログラマーがコードを完璧に記述したとしても、システムの運用中にいくつかの問題が発生します。これは、多くの問題がコードでは回避できないためです。
例外: プログラムの実行中に発生する異常な状況を指し、処理されない場合、最終的に JVM の異常停止につながります。
例外は、構文エラーおよび論理エラーを参照しません。構文が間違っていると、コンパイルが通らず、バイトコード ファイルが生成されず、まったく実行されません。コードのロジックは間違っていますが、目的の結果が得られません。たとえば、a と b の合計を求めるには、ab と書きました。
1.2 例外スローメカニズム
Java では、さまざまな例外がさまざまなクラスで表されます。例外が発生すると、例外タイプのオブジェクトが作成され、スローされます ( throw
)。その後、プログラマーはcatch
この例外オブジェクトをキャッチ () して処理できます。この例外オブジェクトがキャッチされない (catch) 場合、この例外オブジェクトが原因でプログラムが終了します。
シミュレーション プログラムは ArrayIndexOfBoundsException (ArrayIndexOfBoundsException) を生成します。
public class ArrayTools {
// 对给定的数组通过给定的角标获取元素。
public static int getElement(int[] arr, int index) {
int element = arr[index];
return element;
}
}
//测试类
public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = {
34, 12, 67 };
intnum = ArrayTools.getElement(arr, 4)
System.out.println("num=" + num);
System.out.println("over");
}
}
上記のプログラムの実行プロセスの図:
1.3 例外の扱い方
プログラムで発生する例外には、一般に 2 つの解決策があります。1 つは、エラーが発生したときにプログラムの操作を終了することです。もう 1 つの方法は、プログラマーがプログラムを作成するときに考えられるさまざまな例外やエラーを十分に考慮し、それらを防止および回避するために最善を尽くすことです。コードの堅牢性を確保するために、例外検出と例外処理に対応するコードを記述することは、本当にやむを得ません。
2. Java例外システム
2.1 スロー可能
Throwable の一般的なメソッド:
- public void printStackTrace(): 例外の詳細を出力します。
例外の種類、例外の原因、例外の場所が含まれており、開発およびデバッグ フェーズで使用する必要がありますprintStackTrace
。
- public String getMessage(): 例外の理由を取得します。
2.2 エラーと例外
Throwable
Error
と の2 つのカテゴリに分けることができますException
。java.lang.Error
それぞれ2つのクラスに対応java.lang.Exception
。
エラー: Java 仮想マシンが解決できない重大な問題。例: JVM システムの内部エラー、リソースの枯渇、その他の深刻な状況。一般に、処理対象のコードを記述しないでください。
- 例: StackOverflowError (スタック メモリ オーバーフロー) および OutOfMemoryError (ヒープ メモリ オーバーフロー、略して OOM)。
例外: プログラミング エラーまたは偶発的な外的要因によって引き起こされるその他の一般的な問題は、プログラムを実行し続けるために特定のコードで処理する必要があります。そうしないと、例外が発生すると、プログラムもハングアップします。
- ヌルポインタアクセス
- 存在しないファイルを読み取ろうとしました
- ネットワーク接続が失われました
- 配列添字が範囲外です
- …
説明します:
- Error にせよ Exception にせよ、多くのサブクラスがあり、例外の種類は非常に豊富です。コードが異常に実行された場合、特に例外に慣れていない場合は、緊張しないでください。対応する API で例外のクラス名を見つけて、例外の種類を理解してください。
2.3 コンパイル時例外と実行時例外
Java プログラムの実行は、コンパイル時プロセスと実行時プロセスに分けられます。一部のエラーは実行時にのみ発生します。
異常が現れる段階に応じて、異常は次のように分類できます。
- コンパイル時の例外(つまり、チェック済みの例外、チェック済みの例外): コードのコンパイル フェーズ中に、コンパイラは、現在のコードで xx 例外が発生する可能性がある (必ずしもそうであるとは限りません) ことを明確に警告し、プログラマーにそれを処理するコードを書くように明確に促すことができます。前進。プログラマが対応する例外処理コードを記述しない場合、コンパイラはコンパイルが失敗したと直接判断し、バイトコード ファイルを生成できません。通常、この種の例外の発生は、プログラマーのコードが原因ではないか、単純な判断を追加するだけでは回避できません。たとえば、FileNotFoundException (ファイルが見つからない例外) です。
- 実行時例外(つまり、実行時例外、チェックされていない例外、およびチェックされていない例外): コードのコンパイル段階では、コンパイラはまったくチェックせず、コンパイラは例外が発生するかどうかのヒントを提供しません。コードが実行され、xx 例外が発生するまで、それは見つかりません。通常、この種の例外は、プログラマーのコードの記述が不十分であることが原因で発生します。これは、少しの判断または注意深い検査で回避できます。
java.lang.RuntimeException
: クラスとそのサブクラスは実行時例外です。例:ArrayIndexOutOfBoundsException
: 配列添え字の範囲外例外、ClassCastException
型変換例外。
3. 一般的なエラーと例外
3.1 エラー
最も一般的には、2つVirtualMachineError
の古典的なサブクラスがありますStackOverflowError
。OutOfMemoryError
@Test
public void test01(){
//StackOverflowError
recursion();
}
public void recursion(){
//递归方法
recursion();
}
@Test
public void test02(){
//OutOfMemoryError
//方式一:
int[] arr = new int[Integer.MAX_VALUE];
}
3.2 ランタイム例外
@Test
public void test05(){
int a = 1;
int b = 0;
//ArithmeticException
System.out.println(a/b);
}
3.3 コンパイル時の例外
@Test
public void test06() {
Thread.sleep(1000);//休眠1秒 InterruptedException
}
4. 例外処理
4.1 例外処理の概要
プログラムを書くとき、エラーが発生する可能性がある場所に検出コードを追加する必要があることがよくあります.たとえば、x/y 演算を実行する場合、分母が 0 であること、データが空であること、入力がデータではないことを検出する必要があります。しかしキャラクター。if-else 分岐が多すぎると、プログラム コードが長く肥大化し、可読性が低下し、プログラマーは「抜け穴を塞ぐ」ために多くのエネルギーを費やす必要があります。そのため、例外処理メカニズムが採用されています。
Java 例外処理:
Java で採用されている例外処理メカニズムは、例外処理プログラム コードをまとめて通常のプログラム コードから分離することで、プログラムを簡潔で洗練された、保守しやすいものにします。
Java 例外処理方法:
方法 1: try-catch-finally
方法 2:スロー + 例外タイプ
4.2 例外をキャッチする (try-catch-finally)
Java は、例外処理のためのキャッチ アンド スロー モデルを提供します。
- Java プログラムの実行中に例外が発生すると、例外クラス オブジェクトが生成され、例外オブジェクトが Java ランタイム システムに送信されます (このプロセスは、スロー ( ) 例外と呼ばれます)
throw
。 - メソッドで例外がスローされた場合、例外オブジェクトは処理のために呼び出し元メソッドにスローされます。呼び出し元のメソッドで例外が処理されない場合は、呼び出し元のメソッドの上位メソッドにスローされ続けます。このプロセスは、例外が処理されるまで続行されます。このプロセスは、
catch
例外のキャッチ ( ) と呼ばれます。 - 例外が
main()
メソッドに戻り、main() がそれを処理しない場合、プログラムの実行は終了します。
4.2.1 try-catch-finally の基本フォーマット
try{
...... //可能产生异常的代码
}
catch( 异常类型1 e ){
...... //当产生异常类型1型异常时的处置措施
}
catch( 异常类型2 e ){
...... //当产生异常类型2型异常时的处置措施
}
finally{
...... //无论是否发生异常,都无条件执行的语句
}
1. 全体的な実行プロセス:
特定のコードで例外が発生する可能性がある場合、例外がコンパイル時例外 (チェック済み例外) であるか実行時例外 (非チェック例外) であるかに関係なく、try ブロックを使用してそれを囲み、ブロックの下に分岐を記述して、対応する例外オブジェクトをtry
キャッチしてみてください。catch
- プログラムの実行中に try ブロック内のコードで例外が発生しない場合、catch のすべての分岐は実行されません。
- プログラムの実行中に try ブロック内のコードで例外が発生した場合、例外オブジェクトのタイプに応じて、最初に一致した catch 分岐が上から下に選択されて実行されます。このとき、try で例外が発生したステートメントより下のコードは実行されず、try...catch 全体の後のコードは引き続き実行できます。
- プログラムの実行中に try ブロック内のコードで例外が発生したが、どの catch ブランチもその例外に一致 (キャッチ) できない場合、JVM は現在のメソッドの実行を終了し、例外オブジェクトを呼び出し側。呼び出し元がそれを処理しない場合、プログラムはハングします。
2、やってみる:
例外をキャッチするための最初の手順は、try{…}
ステートメント ブロックを使用して例外をキャッチする範囲を選択し、例外を引き起こす可能性のあるビジネス ロジック コードを try ステートメント ブロックに配置することです。
3、catch (Exceptiontype e)
catch
分岐は2つに分かれており、catch()
真ん中に例外の種類と例外パラメータ名が書かれていて、{}
この例外が発生したらどうするかというコードが真ん中に書かれています。- 生成される例外の種類が正確にわかっている場合は、例外クラスを catch のパラメーターとして使用できます。また、その親クラスを catch のパラメーターとして使用することもできます。
たとえば、クラスをArithmeticException
パラメーターとして使用できる場合、そのクラスをRuntimeException
パラメーターとして使用したり、Exception
すべての例外の親クラスをパラメーターとして使用したりできます。ただし、(catch 内のステートメントは実行されません)ArithmeticException
など、クラスに関係のない例外にはなりません。NullPointerException
- 各 try ステートメント ブロックには、生成される可能性のあるさまざまな種類の例外オブジェクトを処理するために、1 つ以上の catch ステートメントを付けることができます。
- 複数の catch 分岐があり、複数の例外の種類に親子関係がある場合は、小さい子の例外の種類が上にあり、大きい親の例外の種類が下にあることを確認する必要があります。それ以外の場合は、エラーを報告してください。
- catch での一般的な例外処理方法
public String getMessage()
: 例外の説明情報を取得し、文字列を返しますpublic void printStackTrace()
: 例外トレース スタック情報を出力し、コンソールに出力します。これには、例外の種類、例外の原因、および例外が発生した場所が含まれます。開発およびデバッグ段階では、printStackTrace() を使用する必要があります。
4.2.2 最後に使い方と例
- 例外によりプログラムがジャンプし、一部のステートメントが実行されなくなるためです。また、プログラムには、例外が発生するかどうかに関係なく実行する必要がある特定のコードがいくつかあります。たとえば、データベース接続、入力ストリーム出力ストリーム、ソケット接続、ロック ロック クローズなど、このようなコードは通常、finally ブロックに配置されます。したがって、通常、finally で実行する必要があるコードを宣言します。
- 唯一の例外は、System.exit(0) を使用して、現在実行中の Java 仮想マシンを終了することです。
- tryコードブロックで異常イベントが発生したかどうか、catch文が実行されたかどうか、catch文で例外が発生したかどうか、catch文でreturnが発生したかどうかに関係なく、finallyブロック内のステートメントが実行されます。 .
- finally ステートメントと catch ステートメントはオプションですが、finally を単独で使用することはできません。
4.3 スローする例外の型を宣言する (throws)
メソッド本体のコードを書く際、特定のコード行にコンパイル時の例外があり、それを処理しないとコンパイルに失敗するが、現在のメソッド本体での処理や合理的な処理に適していない可能性がある場合メソッドを指定できない場合、このメソッドは Exceptions are throw を表示する必要があります。これは、メソッドがこれらの例外を処理せず、メソッドの呼び出し元がそれらを処理する責任があることを示します。
特定のメソッド:メソッド宣言で throws ステートメントを使用して、スローされた例外のリストを宣言します. throws の背後にある例外タイプは、メソッドで生成された例外タイプまたはその親クラスにすることができます.
4.3.1 スローの基本フォーマット
宣言の例外形式:
修飾子の戻り値の型 メソッド名 (パラメータ) throws 例外クラス名 1、例外クラス名 2... { }
throws の後にコンマで区切って複数の例外型を記述できます。
public void readFile(String file) throws FileNotFoundException,IOException {
...
// 读文件的操作可能产生FileNotFoundException或IOException类型的异常
FileInputStream fis = new FileInputStream(file);
//...
}
throws
実行時例外の種類は後で書くこともできますが、実行時例外の種類、書くか書かないかは、コンパイラとプログラムの実行に違いはありません。記述されている場合、唯一の違いは、呼び出し元がメソッドを呼び出した後、try...catch 構造を使用すると、IDEA が追加情報とcatch
追加する必要があるブランチを取得できることです。
4.3.2 メソッド書き換えにおけるスローの要件
メソッドがオーバーライドされた場合:
(1) メソッド名が同じであること
(2) 仮引数リストが同じであること
(3) 戻り値の型が同じであること
- プリミティブ データ型 と
void
: は同じでなければなりません - 参照データ型: <=
(4) パーミッション修飾子: >=、および親クラスのオーバーライドされたメソッドがサブクラスで可視である必要があります
(5)変更されたメソッドは不可static
ですfinal
スロー例外リストの要件:
- 親クラスのオーバーライドされたメソッドのメソッド シグネチャの後に「throws compile-time exception type」がない場合、メソッドが書き換えられると、「throws compile-time exception type」はメソッド シグネチャの後に表示されません。
- 親クラスのオーバーライドされたメソッドのメソッド シグネチャの後に「throws compile-time exception type」が続く場合、メソッドがオーバーライドされると、throws のコンパイル時例外タイプは <= のコンパイル時例外タイプである必要があります。オーバーライドされたメソッドがスローするか、異常なスローなしでコンパイルします。
- メソッドのオーバーライド。「実行時例外タイプをスローする」必要はありません。
4.4 2 つの例外処理方法の選択
例外については、適切な処理を使用してください。このときの例外は、主にコンパイル時例外を指します
- プログラム コードにリソース呼び出し (ストリーム、データベース接続、ネットワーク接続など) が含まれている場合は、それらの使用を検討して、
try-catch-finally
メモリ リークが発生しないようにする必要があります。 - 親クラスのオーバーライドされたメソッドに例外の種類がない場合
throws
、サブクラスのオーバーライドされたメソッドで例外が発生した場合、それは の処理でtry-catch-finally
はなく の処理とのみ見なすことができますthrows
。 - 開発中、メソッド b、c、および d はメソッド a で順番に呼び出され、メソッド b、c、および d 間の関係はプログレッシブです。この時点で、メソッド b、c、および d に例外がある場合、通常はスローを使用することを選択しますが、メソッド a では通常、try-catch-finally を使用することを選択します。
5. 例外オブジェクトを手動でスローします: throw
Java で例外オブジェクトを生成するには、次の 2 つの方法があります。
-
仮想マシンによる自動生成: プログラムの実行中に仮想マシンがプログラムに問題があることを検出すると、現在のコードに対して、例外クラスに対応するインスタンス オブジェクトがバックグラウンドで自動的に作成され、投げた。
-
開発者が手動で作成: 新しい例外タイプ ([実際のパラメーター リスト]);、作成された例外オブジェクトがスローされない場合、通常のオブジェクトを作成するのと同じようにプログラムに影響はありませんが、一度スローがスローされると、プログラムへの影響はありません 操作には影響があります。
5.1 使用形式
throw new 异常类名(参数);
throw ステートメントによってスローされる例外オブジェクトは、JVM によって自動的に作成されてスローされる例外オブジェクトと同じです。
- コンパイル時に例外タイプのオブジェクトである場合は、それを処理するために throws または try...catch も使用する必要があります。そうしないと、コンパイルが失敗します。
- ランタイム例外タイプのオブジェクトである場合、コンパイラはプロンプトを表示しません。
- スローできる例外は、
Throwable
そのインスタンスまたはサブクラスである必要があります。
5.2 使用上の注意
コンパイル時の例外型のオブジェクトであろうと、実行時の例外型のオブジェクトであろうと、try..catch
適切に処理しないとプログラムがクラッシュします。
throw ステートメントにより、プログラムの実行フローが変更されます. throw ステートメントは明示的に例外オブジェクトをスローするため、それ以下のコードは実行されません.
現在のメソッドに例外オブジェクトを処理するための try...catch がない場合、throw ステートメントは return ステートメントを置き換えて、現在のメソッドの実行を事前に終了し、呼び出し元に例外オブジェクトを返します。
6. カスタム例外
6.1 カスタム例外クラスが必要な理由
Java のさまざまな例外クラスは、特定の異常な状況を表します。開発中は、コアクラスライブラリに定義されていない例外が必ず存在するので、その際、自社業務の例外に合わせて、業務に関連する例外クラスを定義する必要があります。
6.2 例外クラスのカスタマイズ方法
(1) 例外種別を継承する場合
コンパイル時の例外タイプをカスタマイズします。カスタム クラスは java.lang.Exception を継承します。
ランタイム例外タイプをカスタマイズします。カスタム クラスは java.lang.RuntimeException を継承します。
(2) 少なくとも 2 つのコンストラクターを提供することをお勧めします。1 つは引数なしのコンストラクターで、もう 1 つは (文字列メッセージ) コンストラクターです。
(3) カスタム例外は serialVersionUID を提供する必要があります
6.3 注意点
- カスタム例外は、throw によってのみスローできます。
- カスタム例外で最も重要なことは、例外クラスの名前とメッセージ属性です。例外が発生した場合、名前から例外の種類を判断できます。例: TeamException("メンバーがいっぱいで、追加できません");
- カスタム例外オブジェクトは、手動でのみスローできます。スロー後は、try...catch で処理するか、呼び出し側でスローを処理できます。
例:
//自定义异常:
public class NotTriangleException extends Exception{
static final long serialVersionUID = 13465653435L;
public NotTriangleException() {
}
public NotTriangleException(String message) {
super(message);
}
}
//手动抛出异常对象
throw new NotTriangleException("输入数据不正确");
7. まとめ
例外処理の 5 つのキーワード:
世界で最も遠い距離は、私が「if」にいて、あなたが「else」にいるときです、私たちはいつも一緒にいて、永遠に離れているように見えます.世界で最も夢中になっているのは、私がケースで、あなたがスイッチであるとき
です
.多分あなたは自分自身を選ぶことができないでしょう;本当の愛では、あなたは試しています、そして私は捕まえています. どんなに腹を立てても、黙って耐え、静かに対処します。それまでは、最後まで楽しみに来てください。