java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.lang.Error
java.lang.ThreadDeath
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。
Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件,表示程序本身可以处理的异常。
Error 是 Throwable 的子类,表示仅靠程序本身无法恢复的严重错误,用于指示合理的应用程序不应该试图捕获的严重问题。
RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try…catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过,这种异常可以通过改进代码实现来避免。
Error类和Exception类都继承自Throwable类。
- Error的继承关系:
java.lang.Object
java.lang.Throwable
java.lang.Error
- Exception的继承关系:
java.lang.Object
java.lang.Throwable
java.lang.Exception
二者的不同之处:
Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked)
2.表示一个由程序员导致的错误
3.应该在应用程序级被处理
Error:
1.总是不可控制的(unchecked)
2.经常用来用于表示系统错误或低层资源的错误
3.如何可能的话,应该在系统级被捕捉
Java 中定义了两类异常:
1) Checked exception: 这类异常都是Exception的子类 。异常的向上抛出机制进行处理,假如子类可能产生A异常,那么在父类中也必须throws A异常。可能导致的问题:代码效率低,耦合度过高。这种异常的特点是要么用try…catch捕获处理,要么用throws语句声明抛出,否则编译不会通过。
2) Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是非凡的,它们不能通过client code来试图解决,所以称为Unchecked exception 。这种异常的特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try…catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过。例如,当除数为零时,就会抛出java.lang.ArithmeticException异常。
Checked Exception与Runtime Exception 的区别
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。异常和继承一样,是面向对象程序设计中经常被滥用的东西,神作《Effective Java》中对异常的使用给出了以下指导原则:
- 不要将异常处理用于正常的控制流(设计良好的API不应该强迫它的调用者为了正常的控制流而使用异常)
- 对可以恢复的情况使用受检异常,对编程错误使用运行时异常
- 避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常的发生)
- 优先使用标准的异常
- 每个方法抛出的异常都要有文档
- 保持异常的原子性
- 不要在 catch 中忽略掉捕获到的异常
受检查异常表示程序可以处理的异常。如果抛出异常的方法本身不处理或者不能处理它,那么方法的调用者就必须去处理该异常,否则调用会出错,连编译也无法通过。当然,这两种异常都是可以通过程序来捕获并处理的,比如除数为零的运行时异常:
<span style="font-family:SimSun;">public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!!!"); try{ System.out.println(1/0); }catch(ArithmeticException e){ System.out.println("除数为0!"); } System.out.println("除数为零后程序没有终止啊,呵呵!!!"); } }
除数为0!
除数为零后程序没有终止啊,呵呵!!!
对于运行时异常,我们不要用try…catch来捕获处理,而是在程序开发调试阶段,尽量去避免这种异常,一旦发现该异常,正确的做法就会改进程序设计的代码和实现方式,修改程序中的错误,从而避免这种异常。捕获并处理运行时异常是好的解决办法,因为可以通过改进代码实现来避免该种异常的发生。
public void test() throws 异常{
程序代码
}catch(异常类型1 异常的变量名1){
程序代码
}catch(异常类型2 异常的变量名2){
程序代码
}finally{
程序代码
}
<span style="font-family:SimSun;"> public void getCustomerInfo() { try { // do something that may cause an Exception } catch (java.io.FileNotFoundException ex) { System.out.print("FileNotFoundException!"); } catch (java.io.IOException ex) { System.out.print("IOException!"); } catch (java.lang.Exception ex) { System.out.print("Exception!"); } }
如果在该方法运行中产生了一个 IOException,输出结果为:
NullPointerException:当操作一个空引用时会出现此错误。
NumberFormatException:数据格式转换出现问题时出现此异常。
ClassCastException:强制类型转换类型不匹配时出现此异常。
ArrayIndexOutOfBoundsException:数组下标越界,当使用一个不存在的数组下标时出现此异常。
ArithmeticException:数学运行错误时出现此异常
注意问题:
public static void main(String[] args) throws FileNotFoundException { Scanner sc = new Scanner(System.in); test(); } public static void test() throws Exception{ System.out.println("file not found"); }
方法中同一种异常只能存在于catch和throws之一,不能同时存在,如下是错的,编译错误:
public static void test() throws FileNotFoundException{ try{ System.out.println("file not found"); }catch( FileNotFoundException e){ e.printStackTrace(); } }
但如下是对的:catch可能还捕获了其他类型能改的异常,而函数声明中只抛出了FileNotFoundException
public static void test() throws FileNotFoundException{ try{ System.out.println("file not found"); }catch( Exception e){ e.printStackTrace(); } }
如下是错的:编译错误,即throws 中声明的错误必须是catch的子类,不可是同等级或者其父类
public static void test() throws Exception{ try{ System.out.println("file not found"); }catch( FileNotFoundException e){ e.printStackTrace(); } }
但如下是对的:
public static void test() throws Exception{ try{ System.out.println("file not found"); throw new Exception();//或者为<span style="font-family: Arial, Helvetica, sans-serif;">throw new <span style="font-family: Arial, Helvetica, sans-serif;">FileNotFoundException <span style="font-family: Arial, Helvetica, sans-serif;">() }catch( FileNotFoundException e){ e.printStackTrace(); } }
对比,如下是错的,编译错误:
public static void test() throws Exception{ try{ System.out.println("file not found"); throw new NullPointerException(); }catch( FileNotFoundException e){ e.printStackTrace(); } }
由此可见,如果throw了某类异常,则可以catch该类异常,同时throws声明,如果throw了某类异常,而catch了其他类型异常,不管有没有throws,都不可以。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/13762.html