首页 > 解决方案 > 嵌套资源获取是否需要在 Java 中进行特殊处理?

问题描述

首先,是的,try-with-resource 解决了这些问题中的任何一个......但如果没有它,我看不出它是如何工作的。

让我们以 java 文档中的这段代码为例,可以在 这里找到:

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}

现在,如果资源br.close()被获取,它就会被释放。然而,

或者我们应该改为编写以下内容以确保不会发生这种情况?

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {

    FileReader fr;

    try {
        FileReader fr = new FileReader(path);
        BufferedReader br;
        try {
            BufferedReader br = new BufferedReader(fr);
            return br.readLine();
        } finally {
            if (br != null) br.close();
        }
    finally {
        // Implements closeable, so it is ok if we call it twice.
        if (fr != null) fr.close();
    }
}


当然,使用 try-with-resources,这种嵌套的混乱仍然消失了,因为我们可以在同一个语句中声明多个资源。但我总是认为自己编写 try-with-resources 是为了避免完全考虑这种情况,并试图在网上找到我真的找不到的解决方案。

任何帮助将不胜感激,谢谢!

标签: javaexceptionnested

解决方案


close()在for的实现中查看 java 源代码BufferedReader

 * @see FileReader
 * @see InputStreamReader
 * @see java.nio.file.Files#newBufferedReader
 *
 * @author      Mark Reinhold
 * @since       1.1
 */

public class BufferedReader extends Reader {

private Reader in;

...
 public void close() throws IOException {
    synchronized (lock) {
        if (in == null)
            return;
        try {
            in.close();
        } finally {
            in = null;
            cb = null;
        }
    }
}
...
  /**
 * Creates a buffering character-input stream that uses an input buffer of
 * the specified size.
 *
 * @param  in   A Reader
 * @param  sz   Input-buffer size
 *
 * @exception  IllegalArgumentException  If {@code sz <= 0}
 */
public BufferedReader(Reader in, int sz) {
    super(in);
    if (sz <= 0)
        throw new IllegalArgumentException("Buffer size <= 0");
    this.in = in;
    cb = new char[sz];
    nextChar = nChars = 0;
}

/**
 * Creates a buffering character-input stream that uses a default-sized
 * input buffer.
 *
 * @param  in   A Reader
 */
public BufferedReader(Reader in) {
    this(in, defaultCharBufferSize);
}

所以 close() 会处理 Reader(此处为 FileReader)并将其设置为 null。
简单BufferedReader br = new BufferedReader(new FileReader(path))就好

嵌套资源获取是否需要在 Java 中进行特殊处理?


这里:没有


推荐阅读