Java 问题是:“;用作资源试用的变量资源应为final或effectivefinal“;

Java 问题是:“;用作资源试用的变量资源应为final或effectivefinal“;,java,resources,try-catch-finally,try-with-resources,Java,Resources,Try Catch Finally,Try With Resources,在我看来,我使用了try with resources,因此我不必在try块中手动关闭资源。因此,如果制作一个FileWriter,我不必尝试,然后捕获并最终关闭它,只需执行以下操作: void m1(){ try(FileWriter fileWriter = new FileWriter ("test.txt")) { //some operations }catch (IOException ioException

在我看来,我使用了try with resources,因此我不必在try块中手动关闭资源。因此,如果制作一个
FileWriter
,我不必尝试,然后捕获并最终关闭它,只需执行以下操作:

void m1(){
        try(FileWriter fileWriter = new FileWriter ("test.txt")) {
            //some operations
        }catch (IOException ioException){
            //some code
        }
    }
但是如果我有一个类引用了已经实例化的
FileWriter
,该怎么办呢?那我就有麻烦了。我想我在这个用例中有一个很大的“漏洞”。有人能指出我遗漏了什么吗?我试着这样做:

public class Test {
    private FileWriter fileWriter;

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

    public void m1 () {
        try(fileWriter) { //compile error
//Says:Variable used as a try-with-resources resource should be final or effectively final
        }catch (IOException ioe){
            //some code
        }
    }
} 

我唯一的目标是(“因为我懒惰”)使用资源的引用自动关闭资源。不幸的是,它不太管用。如何更好地理解为什么会出现引用警告?

如果为try块的作用域声明新变量,则可以对try块之外创建的任何资源使用try with resources。将m1更改为:

public void m1 () {
    try(var autoclosedhere = fileWriter) {
    // or try(FileWriter autoclosedhere = fileWriter) {
        // now fileWriter will close at the end
    }catch (IOException ioe){
        //some code
    }
}

这适用于Java9以后的版本。try子句中需要一个局部变量,以便在fileWriter在块内发生更改时不会出现歧义-请参见。

很有趣,但为什么在我刚刚演示的情况下它不起作用呢?我看不出有什么理由不允许做这样的事。为什么我们必须“欺骗”它并为同一资源使用新变量?您可以在try块内更改fileWriter,因此我猜
try
中变量的声明指示fileWriter值的哪个版本是自动关闭的。