异常

运行时异常:

都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

非运行时异常(编译异常):

是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。如IOException、SQLException等

throw:

如果代码可能会引发某种错误,可以创建一个合适的异常类实例并抛出它,这就是抛出异常。

throws:

在Java中,当前执行的语句必属于某个方法,Java解释器调用main方法执行开始执行程序。若方法中存在检查异常,如果不对其捕获,那必须在方法头中显式声明该异常,以便于告知方法调用者此方法有异常,需要进行处理。 在方法中声明一个异常,方法头中使用关键字throws,后面接上要声明的异常。若声明多个异常,则使用逗号分割。

try-catch底层?

class字节码指令中会有异常表,表示哪一行到哪一行的代码可能有什么异常:

  • from 可能发生异常的起始点
  • to 可能发生异常的结束点
  • target 上述from和to之前发生异常后的异常处理者的位置
  • type 异常处理者处理的异常的类信息

什么时候不走finally?

try或catch中进入了死循环

虚拟机退出

守护线程中可能不会走finally就被回收了

finally的执行顺序

finally正常情况下都会被执行的

如果finally里有return语句,那么它就是整个try-catch-finally结构的返回结果

若没有,就得看try or catch里的return语句了

程序出现了异常会发生什么?

运行时异常:

  • 被try-catch捕获:JVM会将异常对象交给对应的catch处理,异常不会向上抛出(catch块中没有继续抛),处理完后,线程仍然继续执行代码
  • 在方法声明上被抛出:交给上一级的方法进行处理,直到找到能处理该异常的catch块,但运行时异常一般没必要写方法声明上抛出,因为不写同时也不对其try-catch捕获的话,默认就是向上一级方法抛出
  • 无法被处理:没有相应catch块处理,该异常会被交给线程的异常处理器,如果没设置异常处理器,那就走JVM默认的异常处理器,即线程终止,标准输出打印信息,即使有了异常处理器去处理,在处理器处理完后,抛异常的线程仍然会被终止,所以想让线程抛异常后还能继续执行下去,只能用try-catch捕捉异常

非运行时异常:

在编译时就必须被处理,所以和运行时异常走一样的逻辑

如何设置异常处理器?

为特定线程设置处理器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Thread thread = new Thread(() -> { 
// 线程的运行代码
});

thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
// 处理未捕获的异常
System.out.println("线程 " + t.getName() + " 发生异常: " + e.getMessage());
}
});

thread.start();
为所有线程设置默认处理器:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
// 处理未捕获的异常
System.out.println("线程 " + t.getName() + " 发生异常: " + e.getMessage());
}
});

案例:

异常被捕获,仍然执行代码,抛异常之前的代码都能正常执行:

打印:线程仍然执行,i = 10b = 9

定义异常处理器处理异常:

打印:

![](/images/e353185520d693ae246972e875b7ab13.png)

OutOfMemoryError

StackOverflowError

NoClassDefFoundError