繁体   English   中英

Java try-with-resources 的缺点

[英]Disadvantages of Java try-with-resources

我有一种方法可以将文件加载到阅读器中。 测试或其他代码可以使用此阅读器读取文件。 问题是我不能在 try-with-resources/TWR 块之外声明读取器。 这是 TWR 的缺点还是我遗漏了什么?

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TestngTesting {
    BufferedReader fileReader;//Can't declare this as final, because its not assigned here itself.
    BufferedReader fileReader1;

    //Can be made @BeforeClass method.
    public void loadFile() throws IOException {
        fileReader = new BufferedReader(new FileReader("path/file.txt"));

        //Compile error - Variable used as a try-with-resources resource should be final or effectively final.
        try(fileReader){

        }

        try{
            fileReader1 = new BufferedReader(new FileReader("path/file.txt"));
        }finally {
            //end gracefully.
        }
    }
}

PS - 我在发布我的问题之前阅读了这两篇文章 - 链接链接

它不是。

如果你想安全地使用资源,你需要定义一些资源在其中有效的词法范围,并且任何时候代码转换到这个范围之外,它都是无效的。

不这样做意味着编译器或任何 linting 工具都无法跟踪您是否做得对,所以现在它是一个折腾,并且很难检测到错误。 如果你真的想要那个,很酷——但 ARM 已经出来了,ARM 的重点是让词法限制的事情变得简单。

如果您找不到使用 try-with-resources 块 (ARM) 的方法,那么您就没有词法范围的情况。 但是,这并不意味着您立即注定要采用旧的不安全的方式。

可以拥有一个包含资源的字段而不会丢失 ARM

但是,这确实意味着具有该字段的对象本身必须成为AutoClosable - 您可以将 try-with-resources 范围界定的负担转移到调用您的资源使用代码的代码。 然后您要做的就是在您自己的 close() 方法中关闭该资源,如果您implements AutoClosable ,这是您必须实现的唯一方法(这样做可以让其他代码尝试使用您的类的资源实例)。

当然,如果您想要的只是在没有特别合理的理由的情况下移动声明,ARM 确实会“编码”代码样式,您只在需要时声明变量,而不是在顶部声明所有内容的样式。

根据我的经验并仔细阅读各种风格指南,“在顶部声明所有本地变量”并不常见,并且有缺点; 声明是词法范围的。 这是一件好事,对于像 ARM 这样的东西,至关重要。 毕竟,我不想碰这个变量,一旦它已经关闭,绝大多数的资源,这样做与他们任何关闭后()是一个即时异常反正。

问题是我不能在 try-with-resources/TWR 块之外声明读取器。 这是 TWR 的缺点还是我遗漏了什么?

您始终可以在try-with-resources块中声明和初始化它:

try(BufferedReader fileReader = new BufferedReader(new FileReader("path/file.txt"))){
      // Print each line
      String line;
      while ((line = fileReader.readLine()) != null) {
          System.out.println(line);
      }
} catch (IOException e) {
     System.err.format("IOException: %s%n", e);
}

您可以将其重新分配给局部变量:

public class TestngTesting {
    BufferedReader fileReader;

    public void loadFile() throws IOException {
        fileReader = new BufferedReader(new FileReader("path/file.txt"));

        try (BufferedReader r = fileReader) {

        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM