劣等感を感じず、体力を向上させましょう。
インターネット業界で
最高の人は誰ですか?記事があなたにエネルギーをもたらすことができれば、それは最高です!自分を信じて、来
てください〜
例外処理
異常な:
コンピュータプログラムについては、私たちが書いたプログラムが問題を引き起こさないことを保証するものではありません。プログラムの設計に論理的な誤りがなくても、ユーザーが希望どおりに合法的にデータを入力することを保証できますか?ユーザーが公平に協力してくれたとしても、プログラムを実行するときに他の問題が発生しないことを保証できますか?たとえば、ネットワークが突然中断されたり、電源が中断されたりします。
次に、プログラムを設計するときにこれらの問題を考慮して、プログラムを仮想マシンに直接スローしてプログラムを終了させるのではなく、プログラムが正しく実行されない場合に対応する解決策があることを確認する必要があります。
頻繁な例外
- IndexOutOfException:通常、配列の添え字は範囲外の例外です
int[] arr=new int[10];
System.out.println(arr[20]);
- NullPointException:ヌルポインター
String string=null;
string.charAt(0);
- NumberFormatException:数値型変換エラー
String string="abc";
Integer a=Integer.parseInt(string);
- ArithmeticException:算術例外
int a=2;
int b=0;
a=a/b;
- ClassCastException:参照型変換の例外
public class Main {
public static void main(String[] args) {
String string="";
Animal dog=new Dog();
Cat cat=(Cat)dog;
}
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
例外処理メカニズム
方法1:試して...キャッチ
try {
//执行代码
}catch (Exception e){
//解决方案
}
たとえば、1/0を計算すると、算術エラーが発生し、操作中に生成された算術例外をキャッチできます。
try {
int a=2/0;
}catch (ArithmeticException e){
e.printStackTrace();
}
このようにして、算術例外が発生すると、catchステートメントが例外をキャッチして解決します。
- 複数のcatchブロックを使用して、複数の例外をキャッチできます
- ただし、注意してください。小さな例外は上部に配置され、大きな例外は下部に配置されます。
- 大きな例外はその親であるため、一度配置されると、他の小さな例外は実行されません。
- したがって、構造を明確にし、処理をより明確にするために、小さな例外を優先します
tryステートメントブロックでステートメントを実行して例外を生成すると、その後のコードは実行されず、対応するステートメントが例外をキャッチしたcatchブロックで実行されます。
tryステートメントブロックで定義された変数はローカル変数であり、catchステートメントブロックではアクセスできません。
方法2:複数の例外キャプチャ
Java7以降、catchブロックはさまざまな例外をキャッチできます
- 複数の例外をキャプチャする場合は、複数の例外タイプを縦棒で区切ります|
- 複数の例外をキャッチする場合、例外変数は暗黙的にファイナライズされ、例外変数を再割り当てすることはできません。
try {
int a=1/0;
}catch (ArithmeticException |IndexOutOfBoundsException e){
System.out.println("程序产生了算术异常或数组越界异常");
//e=new Exception();改段代码会报错,因为catch括号里面的变量e被final修饰,不可重新赋值
}catch (Exception e){
e=new Exception();
}
マルチ例外キャプチャモードの変数は最終的に変更されるため、catchステートメントブロックで変数を再割り当てすることはできません。
方法3:試して...キャッチ...最後に
ある時点でtryステートメントブロックでいくつかのファイルを開いたり、データベースに接続したりする場合、tryステートメントブロックで例外を生成すると、後続のコードは実行されず、ファイルとデータベースが生成されます。時間内に適切に閉じられません。
- Javaのガベージコレクションメカニズムは、物理リソースを再利用せず、ヒープメモリ内のオブジェクトによって占有されているメモリのみを再利用します。
tryで開かれた物理リソースを時間内に確実に回復できるようにするために、Java例外処理メカニズムはfinallyステートメントブロックを提供します。このステートメントブロックは、tryおよびcatchステートメントブロックの実行後に実行する必要があるコードブロックです。 tryまたはcatchの場合returnステートメントはfinallyの実行に影響しません。finallyが実行された後、returnが実行されます。finallyにreturnステートメントがある場合、tryおよびcatchステートメントブロックのreturnは実行されません。 、ただし、試行中の場合はポイントがあります。System.exit(1)の場合、仮想マシンが直接終了するため、finallyステートメントブロックは実行されません。
FileWriter file=null;
try{
file=new FileWriter("text.txt");
}catch (IOException e){
e.printStackTrace();
}finally {
if(file!=null){
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
このようにして、tryブロックで例外が発生した場合でも、コードは最終的にcloseメソッドを実行してファイルを閉じます。
リソースを自動的に閉じるJava7、9拡張tryステートメント
最終的にリソースを閉じるコードを実行すると、プログラムは非常に肥大化します
Java7:
- Java7は、tryステートメントの機能を拡張します。これにより、tryの直後に括弧のペアをたどることができ、一部のリソースは括弧内で宣言および定義できます。
- tryステートメントの実行が終了すると、プログラムは自動的にリソースを閉じます。
- これらのリソースは、AutoCloseableインターフェースまたはCloseableインターフェースのcloseメソッドを実装する必要があります
- Closeインターフェースは、AutoCloseableのサブインターフェースです。
try (FileWriter file=new FileWriter("text.txt")) {
file.write("");
}catch(Exception e){
e.printStackTrace();
}
Java9:
- Java9はこの操作をさらに強化し、括弧内に宣言および定義する必要はありません。
- tryステートメントの外部で定義できます
- ただし、リソース変数はfinalまたは有効なfinalである必要があります。つまり、他の値が割り当てられたことはありません。
FileWriter file1=new FileWriter("text.txt");
FileWriter file2=new FileWriter("text.txt");
try(file1;file2){
file.write("");
}catch(Exception e){
e.printStackTrace();
}
チェックされた例外とランタイム例外
Javaの例外は、次の2つのカテゴリに分類できます。
1つはチェック例外(コンパイルされた例外)です:
1つはランタイム例外(ランタイム例外)です:
RuntimeExceptionクラスとそのサブクラスのすべての例外はランタイム例外であり、残りはコンパイル時の例外です。
ランタイム例外とは、プログラムの実行後にのみ発生する例外を指します。このような例外はコンパイルには影響しませんが、操作中にエラーが発生します。
ただし、コンパイルするときは、例外を明示的に処理する必要があります。そうしないと、たとえば、複数のスレッドでsleepメソッドを呼び出すときにコンパイルできません。
try ... catchを使用してラップする必要があります。そうしないと、メソッドが定義されたときにコンパイル例外をスローし、明示的に処理する必要があるため、エラーが報告されます。
スローを使用して例外をスローします
- 例外の処理方法がわからない場合は、生成された例外オブジェクトを上向きにスローする必要があります
- メソッドはメインメソッドにスローされます。メインメソッドで解決されない場合は、引き続き上向きにスローされます。
- それをJava仮想マシンにスローし、例外トレーススタック情報を出力して、プログラムを終了します。
- これが、以前に実行したプログラムが失敗した後に終了し、いくつかの赤いエラーがコンソールに出力される理由です。
public static void main(String[] args) throws IOException {
test();
}
public static void test() throws IOException {
int a=2/0;
}
public static void main(String[] args){
try {
test();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void test() throws IOException {
int a=2/0;
}
}
注意:
- しかし、例外をスローするメソッドを呼び出すと、このメソッドはtry ... catchブロックにあります。
- またはスローを使用する別の方法で
- メソッドは例外をスローするので、それをキャッチして解決する必要があるためです
メソッドを書き換えるときに例外をスローする場合の注意事項
サブクラスが親クラスを継承する場合、親クラスのメソッドが例外をスローする場合
サブクラスがこのメソッドをオーバーライドする場合、スローされる例外は、親クラスによってスローされる例外より大きくてはなりません。
class A{
public void test() throws ArithmeticException{
}
}
class B extends A{
@Override
public void test() throws Exception {
}
}
サブクラスBによってスローされた例外は、親クラスによってスローされた例外よりも大きいため、上記のコードはエラーを報告します。
例外をスローするにはthrowを使用します
状況によっては、それが私たちの期待を満たさないアイデアである限り、それは本当の異常ではないかもしれません。
期待に沿わない場合は、手動で例外をスローできます
public static void main(String[] args){
int a=-1;
try {
if(a<0){
throw new Exception("a为负数");
}
}catch (Exception e){
e.printStackTrace();
}
}
チェック例外の場合、明示的にキャッチするか、スローを続行します
Runnable例外、明示的にキャッチするか無視することができます
カスタム例外クラス
Javaで定義されている例外は限られているため、ニーズを満たさない場合があります。現時点では、必要な機能を実現するために、自分で例外クラスを定義する必要があります。
- まず、ExceptionクラスまたはRuntimeExceptionなどの基本クラスを継承する必要があります
- 次に、2つのコンストラクターを定義します
- パラメータ化されたコンストラクタは通常、エラー情報を渡します
class MyException extends Exception{
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
総括する
- 例外は、異常な状況を処理するためにのみ使用されます。通常のプロセス制御を置き換えるために例外を使いすぎないでください。
- 一部の予測可能なエラーの場合、プログラマーは、例外をスローするのではなく、対応するコードを提供して処理することができます。
例えば:
int a[]=new int[10];
for(int i=0;i<100;i++){
try {
System.out.println(a[i]);
}catch (IndexOutOfBoundsException e){
e.printStackTrace();
}
}
-
この状況はプログラマーによって予見可能であり、プログラマーは、
盲目的に例外をスローして解決する代わりに、コードを使用してそのようなエラーを回避することができます。 -
このスロー例外は単純ですが、Javaランタイムが例外をキャッチした後、catchブロックに入る必要があります。
これにより、操作の効率が低下します。 -
例外処理メカニズムの本来の目的は、予期しない例外の処理コードを通常のビジネスロジック処理コードから分離し、
通常のビジネスロジックの判断を置き換えるために例外処理を使用しないことです。