1. 使用 try-catch 捕获单个异常
1.1. 执行语法
try {
//监视代码执行过程, 一旦返现异常则直接跳转至catch,
//如果没有异常则直接跳转至finally
} catch (SomeException e) {
//可选执行的代码块, 如果没有任何异常发生则不会执行;
//如果发现异常则进行处理或向上抛出.
}
1.2. 注意事项
try
和catch
都不能单独使用, 必须要一起使用.catch
代码块如果是捕获单个异常, 则只有在目标异常类型
出现的时候才会跳转执行代码块中的内容, 其他异常类型不会跳转.
1.3. 执行流程
- 先执行 try 中代码块的内容, 如果没有出异常
则跳过catch
代码块; - 如果出现目标异常, 则从异常出现的那一行中断,
try 代码块那一行后面的剩余内容不会执行,
转而跳入catch
代码块当中, 执行其中内容. - 在
try-catch
代码块执行完后, 继续执行代码块之外剩余内容.
2. 使用 try-catch 捕获多个异常
- 一个
catch
只能捕获一种异常, 如果需要捕获多种可能出现的异常, 则需要多个catch
. - 代码在出现异常的瞬间, 只能有一种异常出现, 因此只会执行预设的
catch
中的一个,
并不会在同时触发多种异常并执行多个catch
.
2.1. 执行语法1(异常少量并全部能预知的情况)
- 此时可以把全部异常逐一列举出来, 并可以在返回中写上对应的解决方案信息提示用户.
try { //监视代码执行过程, 一旦返现异常则直接跳转至catch, //如果没有异常则直接跳转至finally } catch (ExceptionA errorA) { //可选执行的代码块, 如果没有任何异常发生则不会执行; //如果发现异常则进行处理或向上抛出. } catch (ExceptionB errorB) { //可选执行的代码块, 如果没有任何异常发生则不会执行; //如果发现异常则进行处理或向上抛出. }
2.2. 执行语法2(不能预知异常类型时)
- 此时直接多态赋值给异常父类
Exception
即可. - 但本方法不便于返回具体的针对措施, 因为异常类型不可预知, 只能返回异常信息.
try { //监视代码执行过程, 一旦返现异常则直接跳转至catch, //如果没有异常则直接跳转至finally } catch (Exception e) { //可选执行的代码块, 如果没有任何异常发生则不会执行; //如果发现异常则进行处理或向上抛出. }
2.3. 执行语法3(混合使用)
- 使用父类
Exception
的catch
必须放在最后, 否则会有语法错误.try { //监视代码执行过程, 一旦返现异常则直接跳转至catch, //如果没有异常则直接跳转至finally } catch (ExceptionA errorA) { //可选执行的代码块, 如果没有任何异常发生则不会执行; //如果发现异常则进行处理或向上抛出. } catch (ExceptionB errorB) { //可选执行的代码块, 如果没有任何异常发生则不会执行; //如果发现异常则进行处理或向上抛出. } catch (Exception e) { //可选执行的代码块, 如果没有任何异常发生则不会执行; //如果发现异常则进行处理或向上抛出. }
3. 获取异常信息
- 一共有以下四个方法, 四个方法定义在
Throwable
类中,
因此所有的错误/异常子类都可以调用以下四种方法获取异常信息.//1. 返回异常发生时的详细信息 public String getMessage();
//2. 返回异常发生时的简要描述 public String toString();
//3. 返回异常对象的本地化信息. // 使用 Throwable 的子类覆盖这个方法, 可以声称本地化信息. // 如果子类没有覆盖该方法, 则该方法返回的信息与 getMessage() 返回的结果相同. public String getLocalizedMessage();
//4. 在控制台上打印 Throwable 对象封装的异常信息, 包括异常类型/原因/代码中出错的位置行号信息. public void printStackTrace();
## 4. finally 代码块的使用
- `finally` 代码块表示最终都会执行的代码, 不论有没有异常.
- `finally` 代码块不能单独使用.
### 4.1. 应用场景
- 当在 `try` 中打开了一些物理资源(磁盘文件/网络链接/数据库链接等),
我们都必须在使用完后关闭这些打开的资源, 因此需要加入 `finally` 代码块.
- 有时候会结合抛出异常(`throws`)来使用, 一般情况下:
- 如果不使用 `finally` 代码块, 那么在抛出异常(`throws`)之后,
就会自动结束程序不再执行余下代码(相当于 `return`);
- 但加上 `finally` 代码块后, 在抛出异常后, 依旧会执行 `finally` 中的内容.
```java
//catch中加入抛出异常的情况
try{
//TODO...
}catch(Exception e){
//TODO...
throws(e);
}finally{
//TODO...
}
只有在
try
或者catch
中调用了退出 JVM 的方法时,finally
代码块
才不会去执行, 否则,finally
代码块将必定会执行.//不会执行finally代码块的情况 try{ //TODO... }catch(Exception e){ //TODO... System.exit(0);//退出JVM }finally{ //TODO... }
若
finally
代码块中包含return
语句, 返回值将必定是finally
代码块
中的结果, 需要避免这种情况的发生.//这种情况下返回结果永远都是 -1; try{ //TODO... return 1; }finally{ //TODO... return -1; }
4.2. 执行语法(两种)
4.2.1. 第一种
- 在这种情况下并不需要
catch
来捕获异常, 因为此时根据应用场景,
会选择抛出异常, 并不需要用户进行处理.try{ //TODO... }finally{ //TODO... }
4.2.2. 第二种
- 这种情况自身需要处理异常, 并最终需要关闭资源.
try{ //TODO... }catch(Exception e){ //TODO... }finally{ //TODO... }