finally 块 - 无法解析变量

finally block - variable cannot be resolved

Java 8

import java.util.zip.GZIPOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


private void createFile(final String json) throws IOException {
        final String fileName = getConfigFileName(this.getSomePath());
        GZIPOutputStream out = null;
        try {
            out = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"));
            out.write(json.getBytes());
        } catch (IOException e) {
            throw e;
        } finally {
            try {
                if (out != null) {
                    out.finish();
                    out.close();
                }
            } catch (IOException e) {
                LOGGER.error("createFile: IOException while closing resources", e);
            }
        }
    }

不错。这个工作正常。 现在我想使用 try-with-resource

private void createFile(final String json) throws IOException {
    final String fileName = getConfigFileName(this.getSomeFile());
    try (GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"))) {
        out.write(json.getBytes());
    } catch (IOException e) {
        throw e;
    } finally {
        try {
            if (out != null) {
                out.finish();
            }
        } catch (IOException e) {
            LOGGER.error("createFile: IOException while closing resources", e);
        }
    }
}

但现在我在这一行中遇到错误:

if (out != null) {

错误是:

out cannot be resolved

我知道这个错误正在上升,因为变量 outfinally 部分。 但是我如何使用 try-with-resources 和执行方法 out.finish ?

从技术角度来看 - 如您所见,在 try 参数中声明的变量在 finally 子句中不可用。这里的好消息是,从函数的角度来看 - finish() 无论如何都不应该在 finally 块中。 finish 是积极(a.k.a“快乐”)流程的一部分,只有在您完成写入流时才应调用。换句话说,如果 write 操作失败并抛出异常,则无论如何都不应该调用 finish

长话短说 - 将 finish 调用移动到 try 块中:

旁注:由于您的方法抛出 IOException,因此没有理由捕获异常并重新抛出它。您可以通过直接从方法调用中抛出代码来清理代码:

private void createFile(final String json) throws IOException {
    final String fileName = getConfigFileName(this.getSomeFile());
    try (GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"))) {
        out.write(json.getBytes());
        out.finish();
    }
}