一、引言
- 本文的知识点既属于IO,又属于异常
- 引入本文知识点之前,先看一个案例
- 通过IO流对象的操作,读取一个字符,会发现下面用了很多的代码
public static void main(String[] args) {
//下面的一大堆代码,仅仅是为了读取一个字符
FileReader fr = null;
try {
//需要把流对象定义在try的外面
fr = new FileReader("I:\\a.txt");
int c = fr.read();
System.out.println((char) c);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//关闭流需要在finally中使用try...catch
//如果fr没有被赋值,这里还可能出现空指针异常
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 为了解决这种繁琐的try...catch问题,引入了本文要说的try-with-resources
二、jdk1.7之后的try-with-resources
- 可以在try后面的小括号中创建流对象,在try...catch机制范围中起作用
- 小括号内的类必须实现Closeable接口或AutoCloseable接口
- 这两个接口都有close方法
- 小括号内只能是创建对象操作,不能是把外面定义的对象直接放在小括号内
- 在try代码块或catch代码块执行完毕后会自动调用close方法
- 小括号内的类必须实现Closeable接口或AutoCloseable接口
public static void main(String[] args) {
try (FileReader fr = new FileReader("I:\\a.txt")) {
int c = fr.read();
System.out.println((char)c);
} catch (IOException e) {
e.printStackTrace();
}
}
- 问题
- fr如果在try...catch之后还要用怎么办?
- 如果fr是外部传入的,执行完try...catch之后还不能关闭怎么办?
- 由此引申出了jdk1.9之后的优化版本
三、 jdk1.9之后的try-with-resources
- jdk1.9之后,可以把定义的变量传进try括号,多个变量使用分号隔开
public static void main(String[] args) {
FileReader fr1 = new FileReader("I:\\a.txt");
PrintWriter fr2 = new PrintWriter("I:\\a.txt");
try (fr1;fr2) {
int c1 = fr1.read();
System.out.println((char)c1);
} catch (IOException e) {
e.printStackTrace();
}
}
- 或者可以在try的小括号中放入自定义类的变量,该自定义类必须实现Closeable接口或AutoCloseable接