我在Java的try-with-resources文档中找到了这个例子:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
如果BufferedReader
的构造函数抛出异常,则FileReader
所拥有的资源将不会被释放。所以这不是一个不好的做法,而不是:
static String readFirstLineFromFile(String path) throws IOException {
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
答案 0 :(得分:1)
确实,只是试了一下:
public class MyFileReader extends FileReader {
public MyFileReader(String fileName) throws FileNotFoundException {
super(fileName);
}
@Override
public void close() throws IOException {
System.out.println("Closing MyFileReader");
super.close();
}
}
public class MyBufferedReader extends BufferedReader {
public MyBufferedReader(Reader in) {
super(in);
throw new RuntimeException();
}
@Override
public void close() throws IOException {
System.out.println("Closing MyBufferedReader");
super.close();
}
}
public String test(String path) throws IOException {
try (BufferedReader br = new MyBufferedReader(new MyFileReader(path))) {
return br.readLine();
}
}
MyFileReader
和MyBufferedReader
都没有关闭......好抓!
同时:
public String test(String path) throws IOException {
try (FileReader fr = new MyFileReader(path); BufferedReader br = new MyBufferedReader(fr)) {
return br.readLine();
}
}
MyFileReader
已关闭。
BufferedReader
构造函数确实可以抛出异常,请参阅BufferedReader(Reader in, int sz)
constructor(虽然不是来自BufferedReader(Reader in)
constructor,但您链接的文档仍应警告此问题恕我直言。)
看起来你赢得了raise an issue:)
的权利答案 1 :(得分:0)
不幸的是,你是对的。
以下示例显示了此行为 - Internal
的实例永远不会关闭。
public class Test {
public static void main(String[] args) {
try (External external = new External(new Internal())) {
}
}
}
class External implements Closeable {
private Internal internal;
public External(Internal internal) {
this.internal = internal;
throw new RuntimeException("boom");
}
@Override
public void close() {
System.out.println("External.close()");
internal.close();
}
}
class Internal implements Closeable {
@Override
public void close() {
System.out.println("Internal.close()");
}
}