一、JAVA中的异常体系
在 Java 中,所有的异常都有一个共同的祖先类 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。Throwable 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。异常和错误的区别是:异常能被程序本身可以处理,错误是无法处理。
二、Error和Exception的区别
Error 错误,一般是指虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用 catch 块来捕获 Error 对象。
由于编译器会对 Error 进行检查,不会强制要求程序员必须处理 Error,因此 Error 也被归入 unchecked 异常分类中(另外:运行时异常也属于 unchecked 异常)。
Exception 表示一种设计或实现问题。也就是说,程序员应该对这些情况进行考虑、并提供相应的处理。
三、运行时异常与一般异常的区别
Checked 异常体现了 Java 的设计哲学:没有完善错误处理的代码根本就不会被执行!
对于Checked异常的处理方式有两种 :
A.当前方法明确知道如何处理该异常,程序应该使用 try...catch 块来捕获该异常,然后在对应的 catch 块中修补该异常。
B.当前方法不知道如何处理这种异常,应该在定义该方法时声明抛出该异常。
运行时异常指的就是 RuntimeException 或其子类的实例,运行时异常则更加灵活,编译器不会强制要求程序员必须处理该异常,运行时异常可以既不显式声明抛出,也不使用try...catch 进行捕捉。但如果程序需要捕捉运行时异常,也可以使用try...catch 块来捕捉运行时异常。
运行时异常的优点在于灵活:程序员想处理就处理,不想处理直接忽略该异常即可。但由于编译器不会强制检查运行时异常,因此程序完全有可能在运行时因为这些异常而结束。
四、常见的运行时异常和受检异常
常见的运行时异常(Runtime Exception):
- NullPointerException - 当调用一个未初始化的引用变量(实际值为 null)的实例 Field、实例方法时都会引发该异常。
- ArithmeticException - 算术异常。比如 5/0 将引发该异常。
- ArrayIndexOutOfBoundsException:数组索引越界异常。
- ClassCastException:类型转换异常。
- IllegalArgumentException:参数非法的异常。
常见的受检时异常(ChenckedException):
- IOException
- RuntimeException
五、Java中的异常处理流程
程序运行过程中可能出现各种“非预期”情况,这些非预期情况可能导致程序非正常结束。为了提高程序的健壮性,Java 提供了异常处理机制:
try{
s1...
s2...
s3...
}
catch(Exception ex){
// 对异常情况的修复处理
}
对于上面处理流程,当程序执行 try 块里的 s1、s2、s3 遇到异常时,Java 虚拟机将会把这个异常情况封装成异常对象,这个异常对象可以被后面对应的 catch 块捕捉到,这样保证这些异常会得到合适的处理。
Java 对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类为 java.lang.Throwable,Throwable 下面又派生了两个子类:Error 和 Exception,Error 错误, 一般是指虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用 catch 块来捕获 Error 对象。
Exception 表示一种设计或实现问题。也就是说,程序员应该对这些情况进行考虑、并提供相应的处理。
异常有可分为 Runtime 异常和 Checked 异常,Checked 异常体现了 Java 的设计哲学:没有完善错误处理的代码根本就不会被执行!对于 Checked 异常的处理方式有两种:
A.当前方法明确知道如何处理该异常,程序应该使用 try...catch 块来捕获该异常,然后在对应的 catch 块中修补该异常。
B.当前方法不知道如何处理这种异常,应该在定义该方法时声明抛出该异常。
实际上 Java 的 Checked 异常后来“争议不断”,因为 Checked 异常要求程序员要么显式声明抛出,要么进行捕捉,不能对 Checked 异常不闻不问,这样就给编程带来了一定的复杂度,比如 Spring、Hibernate 框架的一大特点就是把 Checked 异常包装成了 Runtime 异常。
Runtime 异常则比较灵活,开发者既可以选择捕获 Runtime 异常,也可以不捕获。
来源:oschina
链接:https://my.oschina.net/fairy1674/blog/3182975