一、作用
jdk7之前我们在try-catch-finally中创建资源后,需要手动调用close()来关闭资源。而且关闭资源的代码基本都是固定格式。当我们try-catch中有多个资源时,很容易造成代码冗余!jdk7之后java创作者就为我们提供了一个接口,该接口可以自动为我们关闭资源(实现了该接口的资源)。
该接口只有一个抽象方法close()
AutoCloseable (Java SE 16 & JDK 16)官方API:AutoCloseable (Java SE 16 & JDK 16)
二、之前的try-catch-finally
public class tryCatch {
public static void main(String[] args) throws Exception {
Test test1 = null;
Test test2 = null;
try {
test1 = new Test(1);//开启资源1
test2 = new Test(2);//开启资源2
test1.run();//调用资源1的run()方法
test2.run();//调用资源2的run()方法
} catch (Exception e) {
System.out.println(e.getMessage());//捕获run()方法中的异常
} finally {//关闭资源
if (test1 != null) {
try {
test1.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (test2 != null) {
try {
test2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
class Test implements AutoCloseable {//实现AutoCloseable接口
public int val = 0;//用于区别资源
public Test(int val) {
this.val = val;
System.out.println(val + "流创建");
}
@Override
public void close() throws Exception {//重写 AutoCloseable接口中的close()方法
System.out.println(val + "的close被调用");
}
public void run() {
System.out.println(val + "的run被调用");
// throw new RuntimeException(val + "抛出异常,catch被执行了");
}
}
用于后面的参照,可见代码冗余情况十分明显
三、jdk7之后的try-catch-finally
1.catch块没有执行(没有发生异常)
public class tryCatch {
public static void main(String[] args) throws Exception {
try (Test test1 = new Test(1); Test test2 = new Test(2);) {
//在try后面加一个(),将后面需要关闭的资源放入到这个括号中,系统就会自动为我们关闭这些放入到括号中的资源
test1.run();
test2.run();
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
System.out.println("finally执行了");
}
}
}
class Test implements AutoCloseable {
public int val = 0;
public Test(int val) {
this.val = val;
System.out.println(val + "流创建");
}
@Override
public void close() throws Exception {
System.out.println(val + "的close被调用");
}
public void run() {
System.out.println(val + "的run被调用");
// throw new RuntimeException(val + "抛出异常,catch块被执行了");
}
}
运行结果:
2.catch块执行(发生异常)
public class tryCatch {
public static void main(String[] args) throws Exception {
try (Test test1 = new Test(1); Test test2 = new Test(2);) {
test1.run();
test2.run();
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
System.out.println("finally执行了");
}
}
}
class Test implements AutoCloseable {
public int val = 0;
public Test(int val) {
this.val = val;
System.out.println(val + "流创建");
}
@Override
public void close() throws Exception {
System.out.println(val + "的close被调用");
}
public void run() {
System.out.println(val + "的run被调用");
throw new RuntimeException(val + "抛出异常,catch块被执行了");
}
}
运行结果:
四、总结
-
执行顺序
- 未发生异常
- 执行try块(未发现异常)
- 关闭资源(关闭的顺序和创建资源的顺序相反)
- 执行finally块
- 发生异常
- 执行try块(发现异常处try后面的代码不执行)
- 关闭资源(关闭资源的顺序和创建的顺序相反)
- 执行catch块
- 执行finally块
- 未发生异常
-
使用方式以及注意事项
- 在原先try-catch-finally结构的try后面加一个括号——>try()-catch-finally
- try括号中放需要后序关闭的资源
- 该资源需要直接或者间接实现AutoCloseable接口