今天总结一下Java中的异常和处理机制,首先我们知道Error类和Exception类都是Throwable的子类,Error类以及它子类的实例,代表了JVM本身的错误,程序员无法通过代码处理,因此我们需要去关注Exception类以及它的子类。异常通常可以分为两类,一类是unckecked exception,这类异常在编译时不会提示,通常是代码本身的问题,如除0异常ArithmeticException,数组下标越界ArrayIndexOutOfBoundsException,空指针NullPointerException等。
unckecked exception
1 | public class Untitled { |
这类异常在编译时能够通过,但是运行时会提示错误,诸如此类代码需要程序员自己去进行修改。运行时会提示如下:
1 | Exception in thread "main" java.lang.ArithmeticException: / by zero |
另一类是checked exception,这是除了Error和RuntimeException的其它异常,这类异常强制要求程序员做处理,否则编译不能通过,这样的异常一般是由程序的运行环境导致的,如SQLException,IOException,ClassNotFoundException等。
checked exception
对于checked exception,有两种不同的处理方式:1、使用try…catch…finally语句块处理它,2、在函数申明时使用throws抛给函数调用者去解决。
try…catch…finally语句块
1 | public class ReadFileTest { |
下面我们来讲讲try…catch…finally语句块的注意点:一、异常匹配是按照catch块的顺序从上往下寻找的,只有第一个匹配的catch会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此,如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。二、通常将try、catch、finally三个语句块中都需要用到的变量申明为全局变量,因为可能会重复使用。三、通常try后面必须跟一个catch或finally语句,finally语句块中的代码不管有没有异常,一定执行。
try…catch…finally语句块和return的执行顺序问题
try、catch、finally语句执行顺序:1、try语句中若有异常,进入catch语句捕捉异常,然后执行try语句中剩下的语句,最后进入finally,finally语句块中的内容一定会执行;2、try语句中无异常,try语句块中的语句执行完进入finally;3、如果try语句块中有return,先执行完finally语句,再return。
1 | public class TestReadFile { |
运行结果如下:
1 | aaa |
由于finally中的return会覆盖try或者catch中的返回值,通常建议:1、不要在finally语句块中不要加return语句;2、不要在finally中抛出异常;3、减轻finally的任务,不要在finally中做一些其它的事情,finally语句块仅仅用来释放资源是最合适的。
申明方法时使用throws
这种方法的具体操作是:定义方法时先抛出所有异常,然后谁调用该方法,谁去具体处理,加try/catch处理问题,调用者需要为可能发生的异常负责。
1 | public class TestReadFile { |
throw异常抛出语句
程序员也可以通过throw语句手动显式的抛出一个异常,throw语句的后面必须是一个异常对象,throw语句必须写在函数中,执行throw语句的地方就是一个异常抛出点,它和由JRE自动形成的异常抛出点没有任何差别。
1 | public void save(User user){ |