为什么我不能访问try / catch块中的变量?

时间:2015-08-13 15:59:40

标签: java exception exception-handling try-catch

说我有以下代码:

try {
    Reader reader = new FileReader("/my/file/location");
    //Read the file and do stuff
} catch(IOException e) {
    e.printStackTrace();
} finally {
    reader.close();
}

为什么读者只存在于try括号的范围内?这是为了阻止先前在对象Exception尚未初始化或设置的代码中抛出reader吗?

我应该如何清理try条款中存在的对象,还是必须将它们带到外面?

1 个答案:

答案 0 :(得分:4)

您必须将它们带到外面,否则变量仅存在于try块中。但这是一种改进。如果您将代码更改为:

Reader reader = new FileReader("/my/file/location");
try {
    //Read the file and do stuff
} catch(IOException e) {
    e.printStackTrace();
} finally {
    reader.close();
}

然后try-block中的代码,包括finally,都可以依赖于已经成功创建的阅读器。否则,在您的示例中,如果实例化失败,您的代码仍然会在出路时尝试关闭读取器,该读取器仍为空。

在这个更改的示例中,catch块的实例化引发的异常不会被catch块处理。

问题的组合使你在这里,一个是你更担心尝试用一个catch块来压缩所有异常,而不是在开始调用它之前确保读者处于有效状态。 (你会在JDBC代码中看到这一个 - try-block-to-rule-them-all风格,人们根本无法忍受编写所有嵌套的try块,它太难以容忍了。)另外,它是非常玩具示例,以便像这样在本地捕获所有异常,在现实生活中如果出现问题你想要抛出异常,以便应用程序的其余部分可以知道出错了,给你类似的东西

public void doStuffWithFile() throws IOException {
    Reader reader = new FileReader("/my/file/location");
    try {
        //Read the file and do stuff
    } finally {
        try {
            reader.close();
        } catch (IOException e) {
            // handle the exception so it doesn't mask
            // anything thrown within the try-block
            log.warn("file close failed", e);
        }
    }
}

这与try-with-resources非常相似。 try-with-resources首先创建对象,然后执行try块,然后关闭它创建的东西,确保关闭时抛出的任何异常都不会掩盖try-block中抛出的异常。创建对象仍然有可能抛出异常,它不会被try-with-resources处理。

public void doStuffWithFile() throws IOException {
    try (Reader reader = new FileReader("/my/file/location")) {
        //Read the file and do stuff
    }
}