目录
1 基本概念
程序在运行时,发生了不被期待的意外事件,阻止了程序的正常运行,这就是程序发生了异常。Java提供了异常处理机制,对发生的异常是进行处理。
2 异常的分类
2.1 按照类分类
所有的异常都继承于Throwable类,该类有两个重要的子类:
2.1.1 Error
Error(错误):指程序无法处理的错误异常,通常都与JVM自身运作相关,如OutOfMemonryError(内存溢出异常)。
2.1.1 Exception
Exception(异常):指程序本身可以处理的异常,内含两种类型的异常:
2.1.1.1 运行时异常
运行时异常,即RuntimeException及其子类,此类异常一般是由程序逻辑错误引起,如NullPointerException(空指针异常)。同时Java编译器不会检查它,也就是说,当程序中出现这种异常,即使没有处理也能编译通过。
2.1.1.2 非运行时异常
非运行时异常(编译异常),即RuntimeException及其子类之外的Exception,此类异常发生时,若不处理,程序就不能编译通过,如IOException。
2.2 按照可查性分类
所有的异常可以分为 可查的异常 和 不可查的异常:
2.2.1可查的异常
可查的异常:此类异常编译器要求必须进行处理,这种异常的发生是可以预测的,一旦发生必须进行处理。除了RuntimeException及其子类之外,其他的Exception都属于可查异常。
2.2.1不可查的异常
不可查的异常:此类异常编译器不要求强制处理,通常也无法在程序层面进行处理。Error和运行时异常都属于不可查异常。
3 异常处理机制
Java提供的异常处理机制有两种,分别是 抛出异常 和 捕获异常。
3.1 抛出异常:throw、throws
当系统发生不可查的异常(Error或运行时异常)时,异常将由java运行时系统自动抛出,允许应用程序忽略。
当系统发生可查的异常(非运行时异常),Java规定必须由应用程序进行处理,如抛出异常或者捕获异常进行处理。若抛出异常,则异常由调用者进行捕获处理。
- throw – 通常用在方法体中或者用来抛出自定义异常,并且抛出一个异常对象。程序在执行到throw语句时立即停止,如果要捕获throw抛出的异常,则必须使用try-catch语句。
try{
//抛出异常thorw
String testStr = null; //错误的写法,为了演示
if(testStr == null){
throw new NullPointerException(); //检测为null,故抛出空指针异常
}
System.out.println("后续代码"); //因为上面抛出了异常,故这行后续代码不会运行
}catch(NullPointerException e){ //捕获空指针异常
e.printStackTrace();
}
- throws – 通常被用在声明方法中,用来指定方法可能抛出的异常,多个异常用逗号隔开。throws语句将异常抛给上一级(即调用者),如果不想处理该异常,可以继续向上调用,但最终要有能够处理该异常的代码。
public static void main(String[] args){
try {
testThrowsException(); //此方法中的异常被抛出
} catch (Exception e) { //捕获异常并处理
e.printStackTrace();
}
}
//抛出异常throws
public static void testThrowsException()throws Exception{ //抛出此方法中的所有异常
String testStr = null; //错误的写法,为了演示
System.out.println(testStr.equals("")); //这里会抛出空指针异常
}
3.2 捕获异常:try、catch、finally
- try – 用于监听。将可能抛出异常的代码放在try语句块之中,当try语句块内发生异常时,异常就被监听到。
- catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
- finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物理资源(如数据库连接、网络连接和磁盘文件)。若存在finally块,则代码会在执行try块中除结束相关语句(如return、throw等)之外的代码后,执行finally块,最后再返回try块中执行结束相关语句(如return、throw等) ,但若finally块中存在结束相关语句(如return、throw等) ,则不会返回try块中执行,而是直接结束。
File targetFile = new File("C:\\test.txt"); //指定操作文件
BufferedInputStream bufFis = null; //缓冲流对象
try { //监听下方可能抛出异常的代码
bufFis = new BufferedInputStream(new FileInputStream(targetFile)); //打开缓冲流
//后续处理...
} catch (FileNotFoundException e) { //捕获FileNotFoundException异常
e.printStackTrace(); //异常处理
}finally{ //总会被执行的finally块
if(bufFis != null){
try {
bufFis.close(); //关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
}