异常处理机制
使用try…catch捕获异常
try{
//业务实现代码
}catch(Exception e){
alert 输入不合法
goto retry
}finally{
//回收资源
}
如果执行try块里的业务逻辑代码时出现异常,系统自动生成一个异常对象,该异常对象被提交给Java运行时环境,这个过程称为抛出异常。
当Java运行时环境受到异常对象时,会寻找能处理该异常对象的catch块,如果找到合适的catch块,则把该异常对象交给该catch块处理,这个过程称为捕获异常。
异常类的继承体系
当Java运行时环境接受到异常对象后,会依次判断该异常对象是否是catch块后异常类或其子类的实例,如果是,Java运行时环境将调用该catch块来处理异常,否则再次拿该异常对象和下一个catch块里的异常类进行比较。Java 7 提出了多异常捕获。
Java把所有的非正常情况分为两种:异常(Exception)和错误(Error),它们都继承了Throwable父类。Error应用程序无法处理,不应该用catch来捕获Error对象。也无需在throws子句中声明该方法可能抛出Error及其任何子类。常见的异常:IndexOutOfBoundsException、NumberFormatException、ArithmeticException、NullpointerException。
访问异常信息
所有的异常对象都包含如下几个常用方法:
- getMessage():返回该异常的详细描述字符串。
- printStackTrace():将该异常的跟踪栈信息输出到标准输出错误。
- printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定输出流。
- getStackTrace():返回该异常的跟踪栈信息。
Checked异常和Runtime异常
所有的RuntimeException类及其子类的实例称为Runtime异常;不是的称为Checked异常。
使用throws声明抛出异常:当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用throws声明抛出异常,该异常交给JVM处理。JVM处理异常的方法是,打印异常的跟踪栈信息,并终止程序运行。
语法格式:throws ExceptionClass1,ExceptionClass2...
方法重写时声明抛出异常的限制:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。
使用throw抛出异常:如果需要在程序中自行抛出异常,使用throw语句,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例,可单独使用。
语法格式:throw ExceptionInstance;
自定义异常类: 用户自定义异常都应该继承Exception基类,如果希望自定义Runtime异常,则应该继承RuntimeException基类。
catch和throw结合使用:在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要该方法的调用者中才能完成,所以应该再次抛出异常,让该方法的调用者也能捕获到异常。
catch{
//此处完成本方法中可以对异常执行的修复处理
//仅仅打印异常的跟踪栈信息
e.printStackTrace();
//再次抛出异常
throw new Exception("...");
}
异常链:把捕获一个异常然后接着抛出另一个异常 ,并把原始异常信息保存下来是一种典型的链式处理,成为异常链。
异常跟踪栈:异常对象的printStackTrace()方法用于打印异常的跟踪栈信息,根据输出结果,开发者可以找到异常的源头,并跟踪到异常一路触发的过程。
异常处理规则:
- 使程序代码混乱最小化
- 捕获并保留诊断信息。
- 通知合适的人员。
- 采用合适的方式结束异常活动。