什么是异常
- Java中的异常是在程序运行过程中出现了非正常的情况,导致了JVM非正常终止的情况。
- 在Java语言中,异常自身也是一个类。产生异常的过程就是创建了异常对象并抛出的过程。
- 异常的结构体系如下图所示:
-
Throwable类:表示可抛,是所有异常和错误的超类,两个直接子类为Error和Exception,分别表示错误和异常。
- Error是程序无法处理的错误,是由JVM产生和抛出的,比如
OutofMemoryError
、ThreadDeath
等。这些异常发生时,一般会选择线程终止。 - Exception是程序本身可以处理的异常,对于这类异常,程序应当尽可能地去处理。
- Error是程序无法处理的错误,是由JVM产生和抛出的,比如
-
Exception又分为运行时异常和非运行时异常,这两个异常有很大区别。运行时异常也叫非受检异常,非运行时异常也叫受检异常。
- 运行时异常都是
RuntimeException
类以及其子类异常,比如:NullPointerException
、ArrayIndexOutofBoundsException
等,这类异常也是不受检异常。程序可以选择处理,也可以选择不处理(等出问题再说),这类异常一般由程序逻辑错误引起。 - 非运行时异常即除运行时异常以外的其他情况的类。这些类都属于
Exception
类,比如:IOException
、SQLException
。这类异常写出后马上就会爆红,必须要进行处理。
- 运行时异常都是
异常的处理方式
积极处理
try{} catch{} finally{}
处理方式:如果try{}
代码块中代码运行出现异常,那么catch{}
代码块中代码执行,不影响后面代码执行。无论有没有异常发生,finally{}
的代码一定会执行。
需要注意:
catch{}
只能够捕获给定的异常,对于未给出的异常,catch{}
不会捕获。try{} catch{} finally{}
三个语句均不能单独使用,可以组合:try{} catch{}
、try{} finally{}
、try{} catch{} finally{}
三种。其中catch{}
可以有多个(多写几个catch{}
分别处理不同的错误),finally{}
语句最多有一个。try{} catch{} finally{}
三个代码块中变量的作用域为代码内部,分别独立,不能相互访问。如果要在三个块中使用同一变量,则需要把变量定义到这些代码块之外。- 如果
try{}
中包含多个异常,当抛出一个异常之后就会结束,所以多个catch{}
最多只会匹配其中一个异常类且只会执行该catch{}
块代码,而不会执行其他catch{}
块,匹配顺序从上到下,也有可能所有的catch{}
块都不执行。- 在书写
catch{}
块的时候,应该先书写子类异常,再书写父类异常。(因为catch{}
块从上到下匹配)
- 代码测试:
public static void main (String[] args) {
int[] arr = new int[5];
try {
for (int i = 0; i < 10; i ++) {
arr[i] = i;
}
} catch (Exception e) { //这里创建一个类来接收异常,不确定抛出什么异常可以用父类Exception来接收
System.out.println("数组不赋值了");
}
System.out.println("积极处理异常⬆");
System.out.println("----------------");
}
消极处理
-
throws
处理方式:向外抛出异常,让上一级调用该方法的方法来处理异常。如果是main
方法抛出异常,则会直接交给JVM来处理。 -
throws
和throw
的区别
throws | throw |
---|---|
定义一个方法的时候可以使用throws关键字来声明,表示此方法不处理异常而是交给方法调用者去处理 | 作用是抛出一个异常,自己制造一个异常 |
throws用来声明一个方法可能产生的所有异常,不做任何处理而是将异常向上传递。用在方法声明后,后面跟异常类的名字,可以跟多个异常类名,用逗号隔开 | throw用来抛出一个具体的异常对象,用在方法内部,后面跟异常对象,只能抛一个异常对象 |
throws表示出现异常的一种可能性 | throw表示抛出异常,由方法内部语句或throws抛出处理 |
- 代码测试:
public class Test {
public static void main(String[] args) {
try {
int result = divide(1, 0);
System.out.println(result);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
public static int divide(int numerator, int denominator) throws ArithmeticException {
if (denominator == 0) {
throw new ArithmeticException("除数不能为 0");
}
return numerator / denominator;
}
}