异常处理机制
当程序抛出一个异常后,程序从程序中导致异常的代码处跳出,java虚拟机检测寻找和try关键字匹配的处理该异常的catch块,如果找到,将控制权交到catch块中的代码,然后继续往下执行程序,try块中发生异常的代码不会被重新执行。如果没有找到处理该异常的catch块,在所有的finally块代码被执行和当前线程的所属的ThreadGroup的uncaughtException 方法被调用后,遇到异常的当前线程被中止。
异常的捕获和处理
java异常结构中定义有Throwable类,Exception和Error是其派生的两个子类。其中Exception表示网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常;而Error表示java运行时环境出现的错误,例如:JVM内存资源耗尽等。
try-catch
try{....}语句指定了一段代码,该段代码就是一次捕获并处理例外的范围。
在执行过程中,这段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句分别对这些异常做相应的处理。
如果没有异常产生,所有的catch代码段都被忽略过不执行。
在catch语句块中是对异常进行处理的代码
在catch中声明的异常对象(catch(SomeException e))封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息。
多个catch
每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常。
catch捕获的异常类型由上至下的捕获异常类型的顺序应该是子类到父类的。
try{
.....}catch(NullPointerException e){
......}catch(RuntimeException e){
.......}catch(Exception e){
....}即子类型异常在前,父类型异常在后,这样的顺序依次捕获,否则编译不通过。
finally的作用
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序其他部分以前,能够对程序的状态作统一管理。
无论是try所指的程序块中是否抛出异常,finally所指定的代码都要被执行
通常在finally语句中可以进行资源的释放工作,如关闭打开的文件、删除临时文件等。
throw关键字
当程序发送错误而无法处理的时候,会抛出对应的异常对象,除此之外,在某些时刻,您可能会想到自行抛出异常,例如在异常处理结束后,再将异常抛出,让下一层异常处理块来捕捉,若想要自行抛出异常,您可以使用"throw"关键词,并生成指定的异常对象后抛出。
throw new ArithmeticException();
throws关键字
程序中会声明许多方法,这些方法中可能会因某些错误而引发异常,但您不希望直接在这个方法中处理这些异常,而希望调用这个它的方法来统一处理,这时候您可以使用"throws"关键词来声明这个方法将会抛出异常。
public static void StringToDate(String str) throws ParseException{........}
重写方法时的throws
如果使用继承时,在父类别的某个方法上宣告了throws某些异常.而在子类别中重新定义该方法时,您可以:
不处理异常(重新定义时不设定throws)
可仅throws父类别中声明的部分异常
可throws父类方法中抛出异常的子类异常
但是不可以:
throws出额外的异常
throws父类方法中抛出异常的父类异常
RuntimeException
java异常可以分为可检测异常,非检测异常:
可检测异常:可检测异常经编译器验证,对应声明抛出异常的任何方法,编译器将强制执行处理或声明规则,不捕捉这个异常,编译器就通不过,不允许编译。
非检测异常:非检测异常不遵循处理或者声明规则。在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是否已经解决了这样的一个异常。
RuntimeException类属于非检测异常,因为普通JVM操作引起的运行时异常随时可能发生,此类异常一般是由特定操作引发。但这些操作在java应用程序中会频繁出现。因此他们不受编译器检查与处理或声明规则的限制。
常见RuntimeException
IllegalArgumentException:抛出的异常表明向方法传递了一个不合法或不正确的参数
NullPointerException:当应用程序试图在需要对象的地方使用null时,抛出该异常。
ArrayIndexOutOfBoundsException:当使用的数组下标炒作允许范围时,抛出该异常。
ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出该异常
NumberFormatException:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
PrintStackTrace
Throwable中定义了一个方法可以输出错误信息,用来跟踪异常事件发生时执行堆栈的内容。该方法定义为:
void printStackTrace()
try{
....}catch(Exception e){
e.printStackTrace(); //输出执行堆栈信息
}
getMessage
Throwable中定义了一个方法可以得到有关异常事件的信息。该方法定义为:
String getMessage()
try{
.....}catch(Exception e){
System.out.println(e.getMessage());
}
getCause
很多时候,当一个异常由另一个异常导致异常而被抛出的时候,java库和开放源代码会将一种异常包装成另一种异常。这时,日志记录和打印根异常就变得非常重要了。java异常类提供了getCause()方法来检索导致异常的原因,这些可以对异常根层次的原因提供更多的信息。该java实践对代码的调试或故障排除有很大的帮助。另外,如果要把一个异常包装成另一种异常,构造一个新异常就要传递原异常。
Throwable getCause():获取该异常出现的原因
自定义异常的意义
jave异常机制可以保证程序更安全和更健壮,虽然java类库已经提供很多可以直接处理异常的类,但是有时候为了更加精准地捕获和处理异常以呈现更好的用户体验,需要开发者自定义异常。
继承Exception自定义异常
创建自定义异常类,语法格式:
class[自定义异常类名] extends Exception{..}