java - 为什么可以在 try-with-resources 范围之外使用 Closed 对象?

标签 java httpclient java-7 try-with-resources

I've read在 try-with-resources block 中初始化的资源仅在该 block 的持续时间内有效。

如果是这样,那么这段代码似乎如何解决这个问题?

public class Main {
    public static void main(String[] args) throws Exception {
        final Main main = new Main();

        try {
            final char[] buffer = new char[10];
            StringReader stringReader = main.testStream();
            System.out.println(stringReader.read(buffer, 0, 10));
        } catch (IOException e) {
            System.out.println("expected IOException caught here"); 
        }

        try {
            HttpResponse response = main.tryResponse();
            response.getEntity();
            System.out.println("should not reach this line if response is out of scope");
        } catch (Exception e) {
            System.out.println("why no IOException here?");
        }
    }

    StringReader tryStream() throws IOException {
        try (StringReader reader = new StringReader("string")) {
            return reader;
        }
    }

    HttpResponse tryResponse() throws IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        HttpGet request = new HttpGet("http://www.google.com");
        try (CloseableHttpResponse response = client.execute(request)) {
            return response;
        }
    }
}

对于这种情况,Java 最佳实践是什么?

最佳答案

范围是一个编译时概念,它控制源代码中名称的使用位置。来自 JLS

The scope of a declaration is the region of the program within which the entity declared by the declaration can be referred to using a simple name, provided it is visible (§6.4.1).

换句话说,它不适用于对象(这是一个运行时概念),仅适用于引用它们的变量(和其他命名元素)。

对于您的示例(假设没有return),如果您尝试在try之外使用变量response,它将无法编译 block :

try (CloseableHttpResponse response = client.execute(request)) {    
} 
System.out.println(response); // nope, compilation error

return 语句计算给定的表达式(在本例中为变量),解析一个值(对 CloseableHttpResponse 对象的引用),复制该值,然后返回它,从堆栈中弹出当前方法堆栈帧并将执行返回到调用方法。

使用 try-with-resources 语句,实际的 return 操作前面有一个 finally block ,该 block 调用 close( )response 变量引用的对象上。据推测,这会使对象处于某种无法使用的状态。您可能会遇到运行时异常,具体取决于您随后如何使用它(即在接收返回值的方法中)。

关于java - 为什么可以在 try-with-resources 范围之外使用 Closed 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32999832/

相关文章:

java - HttpPost 转义参数

typescript - HttpClientInMemoryWebApiModule 错误。我可以要两个吗?

java - JDK 日期/时间的问题是否已修复,或者是否仍被视为已损坏?

java - OrientDB 服务器部分忽略 ORIENTDB_HOME

java - 如何在 mac os mavericks 上安装 Netbeans 7.4(已经安装了 jdk 7 update 45)?

Java 在共享位置打开文件

Java jTDS 连接问题 Ubuntu 服务器

Android HTTP 获取

java - Netbeans 平台中的多线程编程

java - 如何抑制 ResponseHeader