为什么可以在其 try-with-resources 范围之外使用 Closed 对象?
Why is it possible to use a Closed object outside of its try-with-resources scope?
I've read 在 try-with-resources 块中初始化的资源仅在该块的持续时间内在范围内。
如果是这样的话,那么这段代码似乎是如何解决这个问题的?
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
,它不会编译:
try (CloseableHttpResponse response = client.execute(request)) {
}
System.out.println(response); // nope, compilation error
A return
语句评估给定的表达式(在本例中为变量),解析值(对 CloseableHttpResponse
对象的引用),复制该值,然后 returns 它,从堆栈中弹出当前方法堆栈帧并将执行返回给调用方法。
对于您的 try-with-resources
语句,实际的 return
操作之前是一个 finally
块,它在 response
引用的对象上调用 close()
多变的。据推测,这会使对象处于某种无法使用的状态。您可能会得到 运行 时间异常,具体取决于您随后如何使用它(即在接收 return
值的方法中)。
I've read 在 try-with-resources 块中初始化的资源仅在该块的持续时间内在范围内。
如果是这样的话,那么这段代码似乎是如何解决这个问题的?
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
,它不会编译:
try (CloseableHttpResponse response = client.execute(request)) {
}
System.out.println(response); // nope, compilation error
A return
语句评估给定的表达式(在本例中为变量),解析值(对 CloseableHttpResponse
对象的引用),复制该值,然后 returns 它,从堆栈中弹出当前方法堆栈帧并将执行返回给调用方法。
对于您的 try-with-resources
语句,实际的 return
操作之前是一个 finally
块,它在 response
引用的对象上调用 close()
多变的。据推测,这会使对象处于某种无法使用的状态。您可能会得到 运行 时间异常,具体取决于您随后如何使用它(即在接收 return
值的方法中)。