赞
踩
在传统的输入输出流处理中,我们一般使用的结构如下所示,使用try - catch - finally结构捕获相关异常,最后不管是否有异常,我们都将流进行关闭处理。
try-with-resources 语句无法管理所有类。Java SE 7 引入了一个新接口 java.lang.AutoCloseable。它的作用就是提供一个名为 close() 的 void 方法,该方法可能抛出一个检查到的异常 (java.lang.Exception)。任何希望在 try-with-resources 语句中使用的类都应实现该接口。强烈建议,实现的类和子接口应声明一种比 java.lang.Exception 更精确的异常类型,当然,更好的情况是,如果调用 close() 方法不会导致失败,就根本不用声明异常类型。
此类 close() 方法已经进行了改进,包含在标准 Java SE 运行时环境的许多类中,这些类包括 java.io、java.nio、javax.crypto、java.security、java.util.zip、java.util.jar、javax.net 和 java.sql packages。这种方法的主要优点在于,现有代码可继续像以前那样工作,而新代码可以轻松利用 try-with-resources 语句。
try { //业务代码 } catch (SQLException e) { // 异常,数据回滚 try { connection.rollback(); } catch (SQLException ex) { log.error(ERROR_MSG, e); throw new IllegalArgumentException(e); } log.error(ERROR_MSG, e); throw new IllegalArgumentException(e); } finally { if (Objects.nonNull(preparedStatement)) { try { preparedStatement.close(); } catch (SQLException e) { log.error(ERROR_MSG, e); throw new IllegalArgumentException(e); } } if (Objects.nonNull(connection)) { try { connection.close(); } catch (SQLException e) { log.error(ERROR_MSG, e); throw new IllegalArgumentException(e); } } }
在jdk1.7之后,推荐使用try() {} catch(IOException e){}的方式来处理io流,它可以自动关闭流。如下所示,是一个简单的按行读取文件内容的示例
@Test
public void readFileContent() {
File file = new File("d://DumpStacks.log");
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
log.info("line : 【{}】" , line);
}
} catch (IOException e) {
log.error("error msg : 【{}】", e);
throw new RuntimeException(e);
}
}
抛异常情况
java.lang.RuntimeException: java.io.FileNotFoundException: d:\DumpStacks.log (系统找不到指定的文件。)
at com.geekmice.springbootselfexercise.NoDaoTest.readFileContent(NoDaoTest.java:347) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.io.FileNotFoundException: d:\DumpStacks.log (系统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.(FileInputStream.java:138)
at java.io.FileReader.(FileReader.java:72)
at com.geekmice.springbootselfexercise.NoDaoTest.readFileContent(NoDaoTest.java:340)
反编译之后可以看到自动关闭流操作
打开target,找到对应字节码文件
@Test public void readFileContent() { File file = new File("d://DumpStascks.log"); try { BufferedReader reader = new BufferedReader(new FileReader(file)); Throwable var3 = null; try { String line; try { while((line = reader.readLine()) != null) { log.info("line : 【{}】", line); } } catch (Throwable var13) { var3 = var13; throw var13; } } finally { if (reader != null) { if (var3 != null) { try { reader.close(); } catch (Throwable var12) { var3.addSuppressed(var12); } } else { reader.close(); } } } } catch (IOException var15) { log.error("error msg : 【{}】", var15); throw new RuntimeException(var15); } }
当使用了try(){}代码块之后,代码执行完毕,就可以进行流的自动关闭,比传统的方式简洁了不少。
try()这部分,可以有多个语句,语句之间分号隔开,也可以同时包含输入流和输出流。最后执行完毕,统一关闭。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。