1.使用try...catch捕捉异常
如果执行try块里的业务逻辑代码时出现异常,系统自动生成一个异常对象,这个异常对象会被提交给Java的运行时环境,把这个过程叫做“抛出异常”
java的运行时环境受到异常对象后,就会寻找这个异常对象的处理catch语句,如果找到合适的,就把这个异常对象交给catch语句块处理,这个过程被称为“捕获异常” 要是捕获不到异常,运行时环境被终止,退出程序
无论处在哪里的代码块,只要出现异常,都会产生异常对象。
2.异常类的继承体系
try{
statement1
statement2
}
catch(ExceptionClass1 e1){
....
}
catch(ExceptionClass2 e2){
....
}
...
每个catch语句里都是处理该异常类及其子类的异常实例
try语句里面的语句出现异常,生成异常对象,运行时环境接收到异常对象后,以此判断该异常对象是否是catch块后异常类或其子类的实例,如果是,将调用该catch块来处理该异常,不会向下进行,否则再次拿该异常对象和下一个catch块里的异常类进行比较
try块里声明的变量时代码块内局部变量,它只在try块内有效,在catch块里不能访问该变量。
异常类的继承树
Java把所有的非正常情况分为两种:异常(Exception)和错误(Error),他们都继承Throwable 父类
Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态连接失败等,这种错误无法恢复或不可能捕捉,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图用catch块来捕获Error对象,在定义该方法时,也无需再其throws子句中声明该方法可能跑出Error及其任何子类
4.多异常捕获
自从java7开始,一个catch块可以捕获多种类型的异常:
1.捕获多种类型的异常时,多种异常类型之间用竖线(|)隔开。
2.捕获多种类型的异常时,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值
5.访问异常信息
d当java运行时决定使用某个catch块来处理该异常对象时,会将异常对象赋给catch块后的异常参数。所有的异常对象都包括了几个方法
getMessage()异常的详细描述字符串
printStackTrace()将该异常的跟踪栈信息输出到标准错误输出
printStackTrace(PrintStream s)将该异常的跟踪栈信息输出到指定输出流
getStackTrace() 返回该异常的跟踪栈信息
6.使用finally回收资源
有些时候,在try块打开了一些系统物理资源(数据库连接、网络连接、磁盘文件等),这些物理资源必须显示回收
为了保证一定能回收try块中打开的资源,异常处理机制提供了finally块,finally块一定会被执行,即使前面出现了return语句,如果在异常处理代码中使用了system.exit(1)(关闭虚拟机)语句,那么finally就失去了执行的机会。
异常处理语句结构里面try是必须的,没有try,就不能有catch和finally,catch和finally至少出现其中之一。
注意:尽量不要在finally块中使用return或throw等导致方法终止的语句。一旦使用,将会使try、catch里面的return、throw失去意义
当java程序执行try、catch时遇到了return或者throw,就会找有没有finally语句,如果有,就会执行finally语句里面的,如果finally里面有return或throw,那么方法就会终止,try、catch里面的语句就失去了执行的机会
7.自动关闭资源的try语句
为了避免代码的臃肿,java7增强了try语句的功能--允许在try关键字后面紧跟一对括号,括号内可以声明、初始化一个或多个资源(必须显示关闭的).try语句在语句结束后自动关系这些资源。这些资源实现类必须实现AutoCloseable或Closeable接口,实现这两个接口必须实现close()方法。
8.Checked异常和Runtime异常
1.RuntimeException类及其子类的实例被称为Runtime异常。
2.不是RuntimeException类及其子类的实例成为Checked异常(只有java提供)
java认为Checked异常都是可以被修复的异常,所以必须被显示处理,如果没有处理,编译就会发生错误。
对Checked的处理方式有两种:
1)、当前方法明确知道如何处理该异常,程序应该使用try。。。catch语句,在对应的catch块中修复该异常
2)、当前方法不知道该如何处理这种异常,在定义该方法时声明跑出该异常
8.1 使用throws声明抛出异常
使用throws声明抛出异常的思路是,当前方法不知道如果处理这种类型的异常,由上一级调用者处理;如果main方法也不知道如何处理,也使用throws声明抛出异常。这个异常将交给jvm处理。JVM对异常的处理方式是,打印异常的跟踪栈信息,并终止程序的运行。throws声明抛出只能在方法签名中使用,一旦使用了throws抛出了异常,就不需要使用try...catch块来捕获该异常了
也就是说,如果某段代码调用了一个带throws声明的方法,该方法声明抛出了checked异常,则表明该方法希望它的调用者来处理该异常(调用该方法时要么放在try块里显示捕获该异常,要么放在另一个带throws声明跑出的方法中)子类方法声明跑出的异常不允许比父类方法声明跑出的异常多
大部分时间下推荐使用Runtime异常,一旦发生了自定义错误,程序只管抛出Runtime异常即可
9.使用throw抛出异常