Java异常分类
-受查异常:
- 编译器可以查出来的异常。必须用try-catch或者throws去处理,如果不处理编译器不会通过。
- 程序认真检查过了,但是运行时还会出现。一般可预计,也容易去处理。
- 除了RuntimeException及其子类外,其他的异常都属于受查异常。
例如: SQLException、IOException、自定义异常。
-非受查异常:
- 编译器不会检查出来的异常,我们可以不去处理,系统自动抛出。
- 一般是由于程序没有认真检查,程序逻辑出现错误引起的。
- RuntimeException及其子类和Error。
例如: IndexOutOfBoundsException(下标越界异常)、NullPointerException、ClassCastException(类型转换异常)等。
异常处理
try-catch
try{
要监控的,可能出现异常的语句;
}catch(异常类1 对象) {
...
}catch(异常类2 对象) {
...
}
finally{
异常的出口
}
//catch可以有一个或者多个来处理不同的异常情况
- try后面一定要有catch或者finally或者两个都有。
- catch语句块可以自定义处理语句,或者使用异常类的方法。
例:
e.getCause():获取异常原因,获取Cause
e.toString(): 获取异常种类和错误信息
e.getMessage(): 获取错误信息
e.printStackTrace(): 对象的堆栈跟踪输出至错误输出流,放在System.err中,并在控制台打印出来,包括异常种类,错误信息,错误位置。
try-catch-finally流程顺序
- try和catch块执行完都会走finally。相当于try-catch的统一出口
- try或catch有return在return前依旧会先走finally。try块或者catch块有return返回值,return的值会放在栈中先不返回,先调用finally块,如果finally块也有return,则会覆盖前面的return返回给上层。
ps: finally中改变了变量会影响之前try的返回值吗?
try返回值会暂时放在栈中新建的局部变量中,如果放的是值,finally执行中改变了原先的变量对返回值不会影响。但如果return的是引用地址(类、list等)finally就会影响try的返回值。
- 当try块出现异常跳到catch块,会直接跳出try块,try块异常后面的代码不会执行
throws和throw
throws
public class Test {
public static void main(String[] args) {
try{
System.out.println(cal(2,0));
}catch (Exception e) {
e.printStackTrace();
}
}
public static int cal(int x, int y) throws Exception {
return x/y;
}
}
- 在方法名处声明可能出现的异常,是一种状态声明。如果出现异常不希望进行处理,就用throws把异常抛给上层处理,上层选择try-catch处理或者继续抛出给上层。最终抛给JVM,JVM打印异常消息和堆栈信息。
throw
public static void main(String[] args) {
try {
throw new Exception("此处抛出异常");
}catch (Exception e) {
e.printStackTrace();
}
}
- throw: 在方法体中抛出一个异常,表示实际动作。常用在当系统检查不出异常,但是你又想在此处抛出异常。