使用try-with-resource需要注意的地方

小灰灰 2023-07-06 09:00 53阅读 0赞

try-with-resource是JDK7引入的语法糖,可以简化Autocloseable资源类的关闭过程,比如JDK7以前下面的代码:

  1. File file = new File("d:/tmp/1.txt");
  2. FileInputStream fis = null;
  3. try {
  4. fis = new FileInputStream(file);
  5. xxxxx
  6. xxxxx
  7. } catch (IOException e) {
  8. e.printStackTrace();
  9. }finally{
  10. if(fis != null){
  11. try {
  12. fis.close();
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }

上面是一段读取文件内容的示意代码,为了防止在try代码块中出现异常后导致的资源泄露问题,在finally代码块中一般处理资源的关闭事项,JDK之后上面的代码就可以简化成下面的写法:

  1. File file = new File("d:/tmp/1.txt");
  2. try(FileInputStream fis = new FileInputStream(file);) {
  3. fis.read();
  4. } catch (IOException e) {
  5. e.printStackTrace();
  6. }finally{
  7. }

可以看出是简化了不少,之所以称之为语法糖,是因为编译成class文件后实际的代码就不是这样的了,编译过程中会自动添加资源的关闭处理,上面的代码编译出的class文件使用javap进行反编译后是下面这样的

  1. File file = new File("d:/tmp/1.txt");
  2. try {
  3. Throwable var2 = null;
  4. Object var3 = null;
  5. try {
  6. FileInputStream fis = new FileInputStream(file);
  7. xxx
  8. xxxx
  9. } catch (Throwable var12) {
  10. if (var2 == null) {
  11. var2 = var12;
  12. } else if (var2 != var12) {
  13. var2.addSuppressed(var12);
  14. }
  15. throw var2;
  16. }
  17. } catch (IOException var13) {
  18. var13.printStackTrace();
  19. }

好了,上面已经引入今天的主题,try-with-resource,但是仍然有需要注意的地方,比如下面的代码:

  1. private static class MyResource implements AutoCloseable{
  2. private MyResource1 res;
  3. public MyResource(MyResource1 res){
  4. this.res = res;
  5. }
  6. @Override
  7. public void close() throws Exception {
  8. System.out.println("MyResource自动关闭");
  9. Integer a = null;
  10. a.toString();
  11. this.res.close();
  12. }
  13. }
  14. private static class MyResource1 implements AutoCloseable{
  15. @Override
  16. public void close() throws Exception {
  17. System.out.println("MyResource1自动关闭");
  18. }
  19. }
  20. @Test
  21. public void test() throws Exception{
  22. try(
  23. MyResource r = new MyResource(new MyResource1())){
  24. Integer a = null ;
  25. a.toString();
  26. }
  27. }

执行上面的代码,由于MyResource的close方法中出现了异常,此时创建的MyResource1就不会被关闭,从而出现资源泄露情况,为了规避这个问题,为了规避这个问题,我们需要创建的实现AutoCloseable接口的对象单独创建,如下面所示:

  1. try(
  2. MyResource1 res= new MyResource1();
  3. MyResource r = new MyResource(res)){
  4. Integer a = null ;
  5. a.toString();
  6. }

发表评论

表情:
评论列表 (有 0 条评论,53人围观)

还没有评论,来说两句吧...

相关阅读