try-with-resources写法
采用try-with-resources写法,当try中代码执行结束(正常结束/异常结束)之后就会调用try()括号中对象的close()方法来关闭资源,虽然表面上来看try-with-resources写法更加优雅

因为实现了autoCLoseAble接口,再try代码块结束后,connection的close方法会自动调用
try{ try(Connection conn = dataSource.getConnection()) { ... String sql = "select * from ..."; try(PreparedStatement statement = conn.prepareStatement(sql)) { ... } } } catch(...) { ... } finally { ... }
在执行完后,conn和其中使用的statement等资源会自动关闭,不需要在finally中手动关闭
|
jdk9新写法
Connection conn = dataSource.getConnection(); try(conn) { ... }
|
示例代码
@Test public void test() throws IOException { String filePath = this.getClass().getResource("test.txt").getPath();
try (FileReader fr = new FileReader(filePath); BufferedReader br = new BufferedReader(fr)) { System.out.println(br.readLine()); } }
|
如上测试用例中,将 FileReader
与 BufferedReader
的声明与创建,放在了 try
括号内,这样即可以无需手动进行资源关闭了。这其实是一个语法糖,使用该特性时,编译器会自动为我们添加调用 close
方法关闭资源的代码。将生成的 .class
文件反编译得到
@Test public void test() throws IOException { String filePath = this.getClass().getResource("test.txt").getPath(); FileReader fr = new FileReader(filePath);
try { BufferedReader br = new BufferedReader(fr);
try { System.out.println(br.readLine());java } catch (Throwable var8) { try { br.close(); } catch (Throwable var7) { var8.addSuppressed(var7); }
throw var8; }
br.close(); } catch (Throwable var9) { try { fr.close(); } catch (Throwable var6) { var9.addSuppressed(var6); }
throw var9; }
fr.close(); }
|
编译器使用传统的 try-finally
写法贴心的为我们添加了资源关闭的代码,而且资源关闭的顺序是:try
括号内先声明的资源后关闭,后声明的资源先关闭。而且关闭资源时,若发生异常,其会将其压制,而抛出 try-with-resources
块内发生的异常。
拓展:自定义 AutoClosable 资源
只要是实现了 AutoClosable
接口的资源,都可以使用try-with-resource特性
static class MyResource implements AutoCloseable { @Override public void close() { System.out.println("my resource closed!"); }
public void doSomething() { System.out.println("do something"); } }
@Test public void myResourceTest() { try (MyResource myResource = new MyResource()) { myResource.doSomething(); } }
|
由此可得,实现 AutoCloseable
接口,只需要实现 close
方法即可,自定义资源与内置资源在 try-with-resources
特性的使用上并无差别。