異常な英語の単語は例外であり、文字通りの翻訳は「事故、例外」を意味します。これは異常な状況を意味します。実際、例外は、プログラムロジックエラーやシステムエラーなど、本質的にプログラムエラーです。
序文
一般に、誰もがJava例外処理に精通しています。2つのポイントがあります。
1。例外をスロー:例外をスローします
class simpleException {public void a()throws Exception {throw new Exception(); };}2.キャッチの例外:
public class myException {public static void main(string [] args){myexception e = new MyException(); SimpleException se = new SimpleException(); try {se.a(); } catch(例外E1){e1.printstacktrace(); }}} class simpleException {public void a()throws Exception {throw new Exception(); };}この記事では、この詳細については、詳細について説明します。
2つのカスタム例外クラス
Java言語は、多くの例外クラスを提供しますが、コードを作成する便利さのために例外クラスをカスタマイズする必要がある場合があります。
クラスSimpleExceptionは例外を拡張します{};
作成後、Try Catchを使用してキャプチャできます。
public class myException {public static void main(string [] args){myexception e = new MyException(); {ea(); } catch(simpleException e1){e1.printstacktrace(); }} public void a()throws simpleException {throw new simpleException(); }} class simpleExceptionは例外{};MyExceptionでメソッドA()を定義し、SimpleExceptionの例外をスローさせ、次にこのメソッドをMain()で呼び出し、Try Catchを使用してこの例外をキャッチします。
myexception.a(myexception.java:15)のmyexception.main(myexception.java:8)at sun.reflect.nativemethodacsessorimpl.invoke0(nativemethodaccessorimpl.invoke(nativemethodaccessorimploke)のsimpleexceptiona(myexception.java:8) sun.reflt.delegatingmethodaccessorimpl.invoke(DelegatingMethodaccessorimpl.java:43)at java.lang.reflt.method.invoke(Method.java:606)at com.intellij.rt.execution.Application.Appmain.main.mainを完成しました。
コンピレーションと実行後の結果は、主に最初の3行に基づいています。説明すべき点がいくつかあります:
1.例外タイプを指定します:(例外仕様)
メソッドで例外をスローする必要がある場合、スローを使用して例外クラスのインスタンスを追加します。このプログラムは、クライアントプログラム(このコードを呼び出すプログラム)に対応する例外をスローし、ここで終了します(戻るのと同等)。また、この方法を定義するときは、例外タイプを指定する必要があることに注意してください。たとえば、次のコードはSimpleExceptionの例外をスローします
public void a()はSimpleExceptionをスローします
2。複数の例外をスローします:
public void a()throws simpleException、aexception、bexception {throw new simpleException(); }異なる例外クラスは、コンマで分離できます。この場合、各例外クラスインスタンス()をスローする必要はありませんが、クライアントコードは各例外クラスをキャッチする必要があります。
public class myException {public static void main(string [] args){myexception e = new MyException(); {ea(); } catch(simpleException e1){e1.printstacktrace(); } catch(bexception e1){e1.printstacktrace(); } catch(aexception e1){e1.printstacktrace(); }} public void a()throws simpleException、aexception、bexception {throw new simpleException(); }} class simpleExceptionは例外を拡張します{}; class aexceptionは例外を拡張します{} class bexceptionは例外を拡張します{} 3つのスタックトレース
例外を投げかけるか、キャッチして例外を扱うかどうかにかかわらず、私たちの目的は、より堅牢なプログラムを作成することです。これは、Java例外メカニズムによって提供される例外情報に大きく依存し、そのキャリアはスタックトレースです。
前のコードでは、printStacktrace()を使用して例外情報を印刷します。実際、getStackTrace()メソッドを使用して、StackTraceElementのコレクションを取得することもできます。手元にアイデアがある場合は、まずStackTraceElementクラスを検索できます。インターフェイスのシリアル化可能なものを実装してから、クラスの説明を確認できます。
/** * {@link * throwable#getStackTrace()}によって返されるように、スタックトレース内の要素。各要素は、単一のスタックフレームを表します。 *スタックの上部にあるものを除くすべてのスタックフレームは、メソッドの呼び出しを表します。スタックの上部にあるフレームは、スタックトレースが生成された *実行ポイントを表します。通常、 *これは、スタックトレース *に対応するスロー可能なものが作成されたポイントです。 * * @Since 1.4 * @Author Josh Bloch */このクラスの各インスタンスは、スタックフレームを表すスタックトレースの要素であり、スタックトレースがgetStackTrace()メソッドによって返されることは明らかです。私は次の数回翻訳しようとしましたが、それは良くないと感じたので、それを説明するためにコードを直接書くことができました:
public class myException {public static void main(string [] args){myexception e = new MyException(); ea(); public void a(){try {throw new Exception(); } catch(Exception E){stacktraceElement [] Ste = E.getStackTrace(); System.out.println(ste.length); }}}メソッドaを定義し、キャプチャ中に例外をスローし、getStackTrace()メソッドを介してスタックトレイセレメントアレイを取得し、配列の長さを印刷します。
7
出口コード0で終了したプロセス
コードを少し変更し、例外をキャッチするのを停止しました。メソッドBを再定義して、Aを呼び出しながら例外をキャッチするようにします。
public class myException {public static void main(string [] args){myexception e = new MyException(); eb(); } public void b(){try {a(); } catch(Exception E){stacktraceElement [] Ste = E.getStackTrace(); System.out.println(ste.length); }} public void a()throws Exception {throw new Exception(); }}結果は次のとおりです。
8
出口コード0で終了したプロセス
心配しないでください、何か面白いことを見てみましょう:
public class myexception {public static void main(string [] args){myexception exceciond = new MyException(); try {exception.c(); } catch(Exception E){stacktraceElement [] Ste = E.getStackTrace(); System.out.println(ste.length); System.out.println("---------------------------------------------------------------"); for(stacktraceElement s:e.getStacktrace()){system.out.println(s.getClassName()+":method"+s.getMethodName()+"at line"+s.getlineNumber()); } System.out.println("---------------------------------------------------------------"); }} public void c()throws exception {try {a(); } catch(例外e){スローe; }} public void a()throws Exception {throw new Exception(); }}結果は次のとおりです。
8---------------------------------------------------------------MyException:method a at line43MyException:method c at line39MyException:method main at line9sun.reflect.NativeMethodAccessorImpl:method invoke0 at line-2sun.reflect.NativeMethodAccessorImpl:method invoke at line57sun.reflect.DelegatingMethodAccessorImpl:method invoke at line43java.lang.reflect.Method:method invoke at line606com.intellij.rt.execution.application.AppMain:method main at line144---------------------------------------------------------------Process finished with exit code 0
つまり、getStackTrace()はスタックを返します。これには、Caller(Main())から最初のスロー例外(A())に基本的な情報が含まれています。上記のコードでは、CメソッドのAメソッドを呼び出したときに例外をキャッチし、スローで再度スローします。 Cメソッドを呼び出すメソッドは、例外をキャッチして処理することができます。または、スローを続けることを選択して、高レベルの発信者(スタックの下部近く)を処理させることができます。 Rethrowは非常に便利ですが、いくつかの問題があります。次のコードを見てみましょう。
public class myexception {public static void main(string [] args){myexception exceciond = new MyException(); try {exception.c(); } catch(Exception e){e.printstacktrace(system.out); }} public void c()throws exception {try {a(); } catch(例外e){スローe; }} public void a()throws exception {throw new Exception( "Exception from A()"); }} java.lang.exception:myexception.a(myexception.java:40)のmyexception.c(myexception.java:30)のmyexception.a(myexception.java:30)のa()からの例外(myexception.java:21)cでeを再投与し、mainでe.printstacktrace()を使用して印刷します。印刷されたスタックトレースがまだ属していることがわかります。スタックトレースをCに変えたい場合は、次のように書くことができます。
public class myexception {public static void main(string [] args){myexception exceciond = new MyException(); try {exception.c(); } catch(Exception e){e.printstacktrace(system.out); }} public void c()throws exception {try {a(); } catch(例外e){// eを投げる; Thro(例外)E.FillinStackTrace(); }} public void a()throws exception {throw new Exception( "Exception from A()"); }} java.lang.exception:myexception.c(myexception.java:22)のa()の例外。 4つの例外チェーン
シナリオを見てみましょう。
public class testexception {public static void main(string [] args){testexception testexception = new testexception(); try {testexception.c(); } catch(cexception e){e.printstacktrace(); }} public void a()throws aexception {aexception aexception = new aexception( "これは例外"); axceptionを投げます。 } public void b()throws bexception {try {a(); } catch(aexception e){新しいbexception( "これはb例外"); }} public void c()throws cexception {try {b(); } catch(bexception e){throw new cexception( "これはc例外です"); }}} class aexceptionは例外を拡張します{public aexception(string msg){super(msg); }} class bexceptionは例外を拡張します{public bexception(string msg){super(msg); }} class cexceptionは例外を拡張します{public cexception(string msg){super(msg); }}3つの例外クラスAException、bexception、およびcexceptionが作成され、その後、aexceptionがa()にスローされ、aexceptionがb()に巻き込まれ、bexceptionがスローされ、最終的にbexceptionはc()に巻き込まれ、cexceptionがスローされ、結果は次のように印刷されます。
Cexception:これは、testexception.c(testexception.java:31)のtestexception.main(testexception.java:8)のC例外です。
わかりました、私たちはセクセプト、aexception、およびbexceptionの情報のみが失われ、例外チェーンの機能が出てきます。コードを参照してください。
public class testexception {public static void main(string [] args){testexception testexception = new testexception(); try {testexception.c(); } catch(cexception e){e.printstacktrace(); }} public void a()throws aexception {aexception aexception = new aexception( "これは例外"); axceptionを投げます。 } public void b()throws bexception {try {a(); } catch(aexception e){//新しいbexception( "これはb例外"); bexception bexception = new bexception( "これはb例外"); bexception.initcause(e); bexceptionを投げます。 }} public void c()throws cexception {try {b(); } catch(bexception e){//新しいcexception( "これはc例外"); cexception cexception = new cexception( "これはC例外です"); cexception.initcause(e);セキシセプトを投げます。 }}} class aexceptionは例外を拡張します{public aexception(string msg){super(msg); }} class bexceptionは例外を拡張します{public bexception(string msg){super(msg); }} class cexceptionは例外を拡張します{public cexception(string msg){super(msg); }}initcause()メソッドを使用して例外情報を接続すると、結果は次のとおりです。
Cexception:これは、testexception.c(testexception.java:35)のt testexception.main(testexception.java:8)のc(testexception.java:8)のC例外です。 sun.reflt.delegatingmethodaccessorimpl.invoke(DelegatingMethodaccessorimpl.java:43)at java.lang.reflt.method.invoke(Method.java:606)at com.intellij.rt.execution.application.Appmain.main(appmain:appmain(appmain)appmain) B(testexception.java:24)のtestexception.c(testexception.java:32)のb(testexception.java:24)... 6 Morecause by:aexception:これはtestexception.a(testexception.java:15)の例外です。
5つのポストスクリプト
実際、Javaの例外処理について議論すべきことはまだたくさんありますが、経験が限られているので、私はそれをあまり深く理解することができず、最も一般的に使用されるものは
try {...} catch(例外e){...}最後に{//例外がキャッチされるか処理されるかに関係なく実行されるコード}しかし、何があっても、例外メカニズムを提供してくれたJavaに感謝する必要があります。それは長老のようなもので、時々私たちを導き、エンコード時に私たちを退屈させません:)