[JAVA]异常
异常的类型
- 每一个异常都是一整个类,它们都继承自Exception类。
异常的类型本质依然是类的对象,但是异常类型支持在程序运行出现问题时抛出,也可以提前声明,高速使用者需要处理可能会出现的异常。
异常分为运行时异常和编译时异常。
运行时异常
- 在编译阶段无法感知代码是否会出现问题,只有在运行的时候才知道会不会出错(正常情况下是不会出错的。
- 这样的异常称为运行时异常,异常也是由类定义的,所有的运行时异常都继承自RuntimeException
编译时异常
- 编译时异常明确指出可能会出现的异常,在编译阶段就需要进行处理(捕获异常)必须要考虑到出现异常的情况,如果不进行处理,将无法通过编译!
- 默认继承自Exception类的异常都是编译时异常。
自定义异常
- 编译时异常之需要继承Exceptio就行了。
- 运行时异常之需要继承RuntimeException就行了。
- RuntimeException继承自Exception,Exception继承自Throwable
抛出异常
- 当别人调用我们的方法时,如果传入了错误的参数导致程序无法正常运行,这时我们就可以手动抛出一个异常来终止程序继续运行下去,同时告知上一级方法执行出现了问题:
1
2
3
4
5
6
7public static int test(int a, int b) {
if(b == 0)
throw new RuntimeException("被除数不能为0"); //使用throw关键字来抛出异常
return a / b;
}
out:
Exception in thread "main" java.lang.RuntimeException: 被除数不能为0 - 异常的抛出同样需要创建一个异常对象出来,我们抛出异常实际上就是将这个异常对象抛出.
- 异常对象携带了我们抛出异常时的一些信息,比如是因为什么原因导致的异常,在RuntimeException的构造方法中我们可以写入原因。
- 程序会终止,并且会打印栈追踪信息.
- 如果我们在方法中抛出了一个非运行时异常,那么必须告知函数的调用方我们会抛出某个异常,函数调用方必须要对抛出的这个异常进行对应的处理才可以:
1
2
3
4private static void test() throws Exception { //使用throws关键字告知调用方此方法会抛出哪些异常,请调用方处理好
throw new Exception("我是编译时异常!");
} - 如果不同的分支条件会出现不同的异常,那么所有在方法中可能会抛出的异常都需要注明:
1
2
3
4
5
6
7private static void test(int a) throws FileNotFoundException, ClassNotFoundException { //多个异常使用逗号隔开
if(a == 1)
throw new FileNotFoundException();
else
throw new ClassNotFoundException();
}
异常的处理
- 当程序没有按照我们理想的样子运行而出现异常时(默认会交给JVM来处理,JVM发现任何异常都会立即终止程序运行,并在控制台打印栈追踪信息)。
现在我们希望能够自己处理出现的问题,让程序继续运行下去,就需要对异常进行捕获,比如:
1
2
3
4
5
6
7
8
9
10
11
12public static void main(String[] args) {
try { //使用try-catch语句进行异常捕获
Object object = null;
object.toString();
} catch (NullPointerException e){ //因为异常本身也是一个对象,catch中实际上就是用一个局部变量去接收异常
}
System.out.println("程序继续正常运行!");
}
out:
程序继续正常运行!当我们希望,程序运行时,无论是否出现异常,都会在最后执行任务,可以交给finally语句块来处理:
1
2
3
4
5
6
7
8try {
//....
}catch (Exception e){
}finally {
System.out.println("lbwnb"); //无论是否出现异常,都会在最后执行
}