ディレクトリ
Javaの例外オブジェクト指向[A]
ジャワの新しい知識を学びながら、最後の学期、試験の週の最後の試験を完了し、私は、コミュニケーションをフーリエ変換のエッジを越えます。より長い時間ではないが、しかし、民間のノート、波の特別要約の完全な。
何がそれをまとめますか?異常!ああ?異常?最近、いくつかの珍しいタッチの人々は...... 1または2を確認するために、質問を磨くために早朝に目が覚めた、奇妙な異常ではありません。異常まあ、よく理解、これは正常な事は間違ったことを行ってきましたです。
二つの整数の割り算を計算:その後、我々は、我々は以前に、単純な十分な例を書いたことを思い出します。別に何か他のものから、あなたが直接、右、次のコードを書くことができます。
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter two integers: ");
int num1 = input.nextInt();
int num2 = input.nextInt();
System.out.println(num1 / num2);
}
この短いコードはリスクがあり、このリスクはおそらく例外に進化します。次に何が起こりますか?私たちは、除数がゼロの場合、Javaの整数計算では、計算式は意味ないだろうことを知っています。私たちの推測で、コンパイルして実行して、軒並み予想通り、利益も。
したがって、我々は結論緋文字を分析:最初の17行に1つのという名前ArthmeticException例外は、実行のメインメソッドが発生している:除算をゼロによる。明らかに、はっきり。
私たちは、例外が発生すると、プログラムが終了します、見ることができ、これは例外メカニズムをスローし、私たちは効率的に問題を発見し、問題を解決することができます。異常なメカニズムは、より良い問題を解決し、堅牢な手続きを確保することです。
そこで、我々はプロセスでそれを取得するには、コードを変更してみてください。
public static int quotient(int num1, int num2) throws ArithmeticException{
if (num2 == 0) {
throw new ArithmeticException("Divisor can not be zero");
}
return num1 / num2;
}
mainメソッドで結果を表示するために呼び出します。
int num1 = input.nextInt();
int num2 = input.nextInt();
try {
System.out.println(QuotientWithMethod.quotient(num1, num2));
}catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
テストに進みます(テストするために、もちろん、我々は、実行時に投げることができませんでした、ここに例外をスロー):
- 二つの数字イニシアチブスロー(スロー)例外の商の方法で
throw new ArithmeticException("Divisor can not be zero");
オブジェクト。 - 宣言は、メソッドがスローされた例外の種類になります定義します
throws ArithmeticException
。 - メソッドが呼び出されたときにメソッドをキャプチャし、
try{...}catch (ArithmeticException e){...}
、と私たちは、例外を処理したい文を実行しますSystem.out.println(e.getMessage());
。
もちろん、上記の例のセットは、例外と例外1で処理し、それだけではないような単純な異常内容は、私たちは以下の内容でどのような異常を探求する探求する必要があることを示す例外がスローされます:
異常な後継システム
不完全な統計だけでなく、より多くの異常な待ち時間がたくさんあるときに珍しいクラス継承図を初めて目には、探求します。
写真は、我々は明らかに本当に正義の名前を知っている参照、これらの異常な知名度は非常に良いです見つけることができます。Throwable
:すべての例外の親クラスが二つの主要なカテゴリがあり、その下に、トップであるException
とError
。以下は、作られた2つの公式文書の説明です:
エラー
合理的なアプリケーションは、深刻な問題がキャプチャするべきではありません表示され、合理的な文法やロジックを指し、。
- 扱うことができない、しようとしないのキャッチをキャプチャするだけで最適化しようとすることができ、。
- これは異常であるとそのサブクラスを必要としないことは、ステートメントスロー彼らがスローする必要はないだろうと述べて、宣言を。
- 彼らはに属していない異常な被験者(未チェック例外)。
このような動的リンク障害などの仮想マシンのエラーは、このようなシステムクラッシュとして、仮想マシンに関連付けられています
例外
- そして、エラー差があるが、例外はクラスを表し問題は、アプリケーションの合理的な外観で取り扱うことができます。
- 加えて、特別な場合のRuntimeExceptionのサブクラスではなく、例外その他の例外クラスは、被写体異常(例外をチェックします)。
異常かどうかを検討
未チェック例外(ではない未確認の例外)
也叫运行时异常,由Java虚拟机抛出,只是允许编译时不检测,在没有捕获或者声明的情况下也一样能够通过编译器的语法检测,所以不需要去亲自捕获或者声明,当然要抛出该类异常也是可以的。典型的异常类型:Error及其子类异常,RuntimeException及其子类异常。注意:RuntimeException代表的是一类编程错误引发的异常:算数异常、空指针异常、索引越界异常、非法参数异常等等,这些错误如果代码编写方面没有任何漏洞,是完全可以避免的,这也是不需要捕获或者声明的原因,也有助于简化代码逻辑。
checked expections(受检异常)
也叫编译时异常,Java认为受检异常需要在编译阶段进行处理, 必须在显式地在调用可能出现异常的方法时捕获(catch),或者在声明方法时throws异常类型,否则编译不会通过。除了上面提到的Exception及其子类都属于受检异常,当然,不包括上面提到的RuntimeException。
异常的处理方式
我们上面提到,我们无法去直接处理不受检异常,但是我们必须强制地对可能发生受检异常(编译时异常)的行为做处理,处理方法主要有以下:
- 在当前方法中不知道如何处理该异常时,直接在方法签名中throws该异常类型。
public void m1() throws ClassNotFoundException, IOException {
//to do something
}
- 在当前方法中明确知道如何处理该异常,就使用
try{...}catch{...}
语句捕获,并在catch块中处理该异常。
public void m3() {
try {
m1();
} catch (ClassNotFoundException e) {
//to do something
} catch (IOException e) {
//to do something
}
}
也可以直接捕获Exception的实例,因为它是这些异常的父类,但是上面的捕获异常引发的错误会更加直接一些。
public void m2() {
try {
m1();
} catch (Exception e){
//do something
}
}
如果处理不了,就一直向上抛,直到有完善解决的办法出现为止。当然我们也可以自行抛出系统已经定义的异常:
public void m2(int i) throws IOException, ClassNotFoundException {
if (i >1)
throw new IOException("!");
throw new ClassCastException();
}
需要注意的是:
- 用throw语句抛出异常的实例!注意是异常的实例!且一次只能抛出一个异常!
- throw和throws是不一样的!睁大眼睛!一个是抛出异常实例,一个是声明异常类型。
- 创建异常实例可以传入字符串参数,将被显示异常信息。
自定义异常
我们知道,程序发生错误时,系统会自动抛出异常。那么,我们如果想独家定制一个属于自己的异常可以不?答案显然是可以的,情人节快到了,直接自定义一个异常:
class noGirlFriendException extends Exception{
noGirlFriendException(){
}
noGirlFriendException(String msg){
super(msg);
}
}
需要注意的是:
- 如果自定义异常继承RuntimeException,那么该异常就是运行时异常,不需要显式声明类型或者捕获。
- 如果继承Exception,那么就是编译时异常,需要处理。
- 定义异常通常需要提供两个构造器,含参构造器传入字符串,作为异常对象的描述信息。
异常的捕获方式
- 每个异常分别对应一个catch语句捕获。
- 对所有异常处理方式相同,用父类接收,向上转型,Exception对应的catch块应该放在最后面,不然的话,在他后面的块没有机会进入处理。下面就是一个典型的错误示范:
//下面的形式错误!
public static void main(String[] args) {
try {
System.out.println(1 / 0);
} catch (Exception e) {
e.printStackTrace();
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
}
- JDK1.7之后,可以分组捕获异常。
- 异常类型用竖线分开。
- 异常变量被隐式地被final修饰。
try {
System.out.println(1 / 0);
} catch (ArithmeticException | NullPointerException e) {
//捕获多异常时,异常变量被final隐式修饰
//!false: e = new ArithmeticException();
System.out.println(e.getMessage());
}
本文参考诸多资料,并加上自身理解,如有叙述不当之处,还望评论区批评指正。关于异常,还有一部分内容,下篇进行总结,晚安。
参考资料:
https://stackoverflow.com/questions/6115896/understanding-checked-vs-unchecked-exceptions-in-java
https://www.programcreek.com/2009/02/diagram-for-hierarchy-of-exception-classes/