一、简介
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
Exception和Error都继承于Throwable类,在Java中只有Throwable类型的实例才可以被抛出或捕获,它是异常处理机制的基本组成类型。
Exception是可预料的异常情况,可以获取到这种异常,并对其进行业务外的处理。
Error是不可预料的异常,error发生后,会直接导致JVM不可处理。
Exception分为检查性异常和非检查性异常。
检查性异常,必须在编写代码的时候就要进行处理,使用try catch捕获或抛出异常。
非检查性异常编译器不会发现这个地方是否会发生异常,比如空指针异常,这种异常是在代码编写或使用过程中通过规范可以避免发生的。
二、语法
1.try语句
try语句用大括号包含一段代码,该段代码可能会抛出一个或多个异常。
2.catch语句
catch语句的参数类似于方法的声明,包括一个异常类型和一个异常对象。异常类型必须为Throwable类的子类,它指明了catch语句所处理的异常类型。异常对象则由运行时系统在try所指定的代码块中生成并被捕获,大括号中包含对象的处理,其中可以调用对象的方法。
catch语句可以有多个,分别处理不同类的例外。Java运行时系统从上到下分别对每个catch语句处理的例外类型进行检测,直到找到类型相匹配的catch语句为止。这里,类型匹配指catch所处理的例外类型与生成的例外对象的类型完全一致或者是它的父类,因此,catch语句的排列顺序应该是从特殊到一般。
3.finally语句
不管try是否会抛出异常,finally语句中的代码都会执行,finally语句块中的作用是释放资源。
4.throws语句
throws出现在方法头后,用来标明该方法可能抛出的异常。
5.throw语句
与throws异曲同工,只是位置不一样,throw放在catch模块中,程序遇到throw后立即终止,throw后的代码不执行,finally除外。
6.抛出异常
package day01;
import day02.Student;
import java.io.*;
import java.util.*;
/**
* @author qx
* @date 2023/7/28
* @des 异常
*/
public class Demo {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("D:" + File.separator + "demo.txt");
FileInputStream outputStream = new FileInputStream(file);
}
}
7.捕获异常
package day01;
import day02.Student;
import java.io.*;
import java.util.*;
/**
* @author qx
* @date 2023/7/28
* @des 异常
*/
public class Demo {
public static void main(String[] args) {
File file = new File("D:" + File.separator + "demo.txt");
FileInputStream outputStream = null;
try {
outputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("释放资源");
}
}
}
三、trycatch的执行顺序
- 从try中第一行代码开始执行,执行到出现异常的代码,JVM会创建一个异常对象。
- 判断catch是否能捕获到jvm创建的异常对象,① 如果捕获到就跳到catch代码块中,不会结束程序,继续从catch中的代码逻辑;② 如果捕获不到,直接打印异常信息并结束程序。
- 如果try中没有异常,则执行完try中代码,跳过catch,进入finally代码块。
四、异常处理原则
1.方法内如果抛出需要检测的异常,那么方法上必须要声明,否则必须在方法内用try-catch捕获,否则编译失败。
2.如果调用了声明异常的函数,要么try-catch处理要么throws向上抛出异常,否则编译失败。
3.什么时候catch,什么时候throws?功能内容可以解决,用catch,解决不了,用throws告诉调用者,有调用者解决。
4.如果一个功能抛出了多个异常,那么调用时必须有对应多个catch进行针对性处理。
五、工作过程中总结的使用try的注意事项
- 尽量不要直接捕获Exception,而是应该先捕获特定异常,最后捕获Exception异常。因为写代码也是一门学问,要让读代码的人可以从代码中获取更多的信息。
- try中不应放过多的代码,只放必须放的就可以了,放太多的话如果发生异常,异常后面的代码将不会被执行。
- catch可以有多个,而捕获的异常,应按优先级捕获,先捕获最低级别的异常,以此类推。
- finally在trycatch语法中是选用的,不必须有,但如果有,不管是否发生异常,finally中的代码都会最后执行,finally中常见的操作是对流进行关闭,或者删除某些操作完的文件等。
- 当你对一段代码进行trycatch时,catch中一定要做处理,一般会给定返回值,boolean类型、整形一般根据实际情况返回-1、String或者集合类型一般返回null,然后再调用处进行返回值判断,坚决避免catch中不做任何处理,亦或返回了,但没接收。