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/