异常处理办法之一:try/catch
执行顺序
- 遇到异常,跳出try,执行catch里面的语句
不管是否遇到异常,finally里面的代码都会被执行,但是后面的就不会。
try介绍
异常如何被抛出
package cn.haien.trycatch;
import java.io.*;
/**- 关于FileInputStream的try/catch测试
- @author 14103
/
public class TryCatch03 {
public static void main(String[] args) {
}String str = new TryCatch03().openFile(); System.out.println(str);
String openFile() {
执行try、catch语句,给返回值赋值try { System.out.println("aaa"); //创建文件字节读取流对象fis FileInputStream fis = new FileInputStream("D:\\test.txt");//将字符串路径封装成File对象 int a = fis.read();//返回读取到的字节 System.out.println("bbb"); System.out.println(a); return "step1"; }catch(FileNotFoundException e) { e.printStackTrace(); System.out.println("catch!!!"); return "step2"; }catch(IOException e) { e.printStackTrace(); return "step3"; }finally { //这里忽略关闭文件操作 System.out.println("finally1!!"); //return "fff"; //如果这里加入return,那么返回值一定是fff了,因为会覆盖前面的返回值 } /*总结:执行顺序
执行finally
return*/
}
}异常处理办法之二:声明异常——throws
作用
谁调我往谁抛出,就谁来处理手动抛出
可以在try里面自己new一个异常对象然后抛出,称为手动抛出,用得不多
try-with-resource及其异常抑制
背景
- 在Java编程中,如果打开了外部资源(文件、数据库连接、网络连接等),必须在使用完毕后关闭。因为外部资源不由JVM管理,无法享用JVM垃圾回收机制,如果我们不在编程时确保关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用、数据库连接过多导致数据池溢出等严重问题。
传统的资源关闭方式
通常关闭代码被写入finally代码块中,当然我们还必须注意到关闭代码时可能抛出的异常。
public static void main(String[] args) { FileInputStream inputStream = null; try { inputStream = new FileInputStream(new File("test")); System.out.println(inputStream.read()); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } } }
JDK7及以后的try-with-resource资源关闭方式
当一个外部资源的句柄对象(比如FileInputStream对象)实现了AutoCloseable接口,那么上述代码就可以简化为如下形式:
public static void main(String[] args) { try (FileInputStream inputStream = new FileInputStream(new File("test"))) { System.out.println(inputStream.read()); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } }
- 将外部资源的句柄对象的创建挡在try关键字的括号之中,当这个try/catch代码块执行完毕后,Java会确保外部资源的close方法被调用。代码简介许多。
实现原理
try-with-resouce并不是JVM的新增功能,而是JDK实现的一个语法糖。将以上代码反编译后如下:
public static void main(String[] args) { try { FileInputStream inputStream = new FileInputStream(new File("test")); Throwable var2 = null; //定义一个即将抛出的异常 try { System.out.println(inputStream.read()); } catch (Throwable var12) { //对资源进行处理(读或写)时遭遇异常 var2 = var12; //获取这个异常 throw var12; //并抛出 } finally { if (inputStream != null) { if (var2 != null) { //如果前面抛出了异常 try { inputStream.close(); } catch (Throwable var11) { var2.addSuppressed(var11); //则将关闭时遭遇的异常信息添加到前面的异常,控制台只打印处理异常,但通过异常的getSupperssed方法,可以提取出被抑制的关闭异常 } } else { inputStream.close(); //如果前面无异常,那么关闭异常将被抑制 } } } } catch (IOException var14) { throw new RuntimeException(var14.getMessage(), var14); } }