【问题标题】:finally block - variable cannot be resolvedfinally 块 - 变量无法解析
【发布时间】:2022-01-24 22:48:49
【问题描述】:

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 呢?

【问题讨论】:

  • 1) 您要么必须将其提取到 try-with-resources 块中的变量,例如 GZIPOutputStream out; try ( GZIPOutputStream autoClosedOut = out ) { ... } finally { do-your-out-things }(try-expression 的怪异语法随后在 Java 的更高版本中得到修复) ; 2)或者将finish方法封装到close方法中,使其可以“自动完成”; 3)或者,假设前两个是通用的,确保GZIPOutputStream在关闭时执行finish(必须在源代码右侧的JavaDocs中声明以确保)。

标签: java-8 compiler-errors try-catch-finally try-with-resources


【解决方案1】:

从技术角度来看 - 如您所见,try 参数中声明的变量在 finally 子句中不可用。这里的好消息是,从函数的角度来看 - finish() 无论如何都不应该在 finally 块中。 finish 是积极(又名“快乐”)流的一部分,只有在您完成写入流时才应调用。换言之,如果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();
    }
}

【讨论】:

猜你喜欢
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 2012-04-14
  • 1970-01-01
  • 2020-01-17
  • 2021-12-17
相关资源
最近更新 更多