首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Java 9中的尝试资源增强

理解Java 9中的尝试资源增强
EN

Stack Overflow用户
提问于 2020-11-04 21:32:06
回答 2查看 106关注 0票数 1

与其在中初始化资源,不如尝试使用资源阻止,如下所示:

代码语言:javascript
复制
try(FileWriter fw = new FileWriter ("java.txt")) {
    //some operation
}catch (IOException ioe) {
    ioe.printStackTrace ();
}

,我们现在只需传递一个对的引用,使用资源块,我们希望自动关闭它,如下所示:

代码语言:javascript
复制
FileWriter fw = new FileWriter ("java.txt");

try(fw) {
    //some operation
}catch (IOException ioe){
    ioe.printStackTrace ();
}

到目前为止这部分已经很清楚了。我的问题是,为什么我将在下一个示例中显示的代码不起作用?它与上一个编译得很好的示例有什么不同?

代码语言:javascript
复制
public class Test {

    private FileWriter fileWriter;

    public Test (FileWriter fileWriter) throws IOException {
        this.fileWriter = fileWriter;
    }

    {
        try(fileWriter) { //compile error:
//"Variable used as a try-with-resources resource should be final or effectively final""
        }catch (IOException ioe){
            ioe.printStackTrace ();
        }
    }

}

有人能帮我理解这条信息到底意味着什么吗?我不知道这里有什么问题。我还尝试将最终放在fileWriter变量声明中,这并没有解决问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-04 22:08:05

我得到以下编译器错误,与您的不匹配:

代码语言:javascript
复制
The blank final field fileWriter may not have been initialized

这是因为您在实例初始化器中引用了fileWriter,它在超类构造函数调用和显式构造函数调用之后执行,但在构造函数中的任何剩余代码之前执行。根据JLS,第12.5节,“创建新类实例”

  1. 将构造函数的参数分配给此构造函数调用的新创建的参数变量。
  2. 如果该构造函数以同一个类中的另一个构造函数的显式构造函数调用(§8.8.7.1)开始(使用此方法),则使用这五个步骤递归地计算参数和处理构造函数调用。如果构造函数调用突然完成,则此过程出于同样的原因突然完成;否则,继续执行步骤5。
  3. 此构造函数不以同一类中的另一个构造函数的显式构造函数调用开始(使用此方法)。如果此构造函数用于对象以外的类,则此构造函数将以超类构造函数的显式或隐式调用(使用超级)开始。使用这五个步骤递归地评估超类构造函数调用的参数和过程。如果构造函数调用突然完成,则此过程出于同样的原因突然完成。否则,继续执行步骤4。
  4. 为该类执行实例初始化器和实例变量初始化器,将实例变量初始化器的值按从左到右的顺序分配给相应的实例变量,这些变量在类的源代码中以文本形式出现。如果执行这些初始化程序中的任何一个都会导致异常,那么将不再处理其他初始化器,并且该过程在相同的异常下突然完成。否则,继续执行步骤5。
  5. 执行此构造函数主体的其余部分。如果该执行突然完成,则此过程出于同样的原因突然完成。否则,此过程将正常完成。

(粗体强调地雷)

这意味着构造函数尚未将任何东西分配给fileWriter,从而导致了实际的错误。

在初始化fileWriter之后,或者在构造函数中放置try-with块,或者将其移动到一个方法中。

票数 3
EN

Stack Overflow用户

发布于 2020-11-04 21:40:46

本质上,这意味着Java希望您确保传递来尝试使用--资源(在本例中是fileWriter)的变量在被分配后不会被更改。如果可以更改变量(例如在try块本身中),那么可能会出现各种未定义的行为。

从代码的角度来看,要完成这项工作,请在final的声明中添加fileWriter

代码语言:javascript
复制
public class Test {

    private final FileWriter fileWriter;  // add 'final'

    public Test (FileWriter fileWriter) throws IOException {
        this.fileWriter = fileWriter;
    }
 
    // ... in some other method
    private void foo() {
        try(fileWriter) {
        } catch (IOException ioe){
            ioe.printStackTrace ();
        }
    }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64688022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档