首页 > 解决方案 > Problem with: "Variable used as a try-with-resources resource should be final or effectively final"

问题描述

From my point of view, I use try with resources so I don't have to close resources manually in try block. So in case of making a FileWriter, I wouldn't have to try, then catch and close it in finally, but just do this:

void m1(){
        try(FileWriter fileWriter = new FileWriter ("test.txt")) {
            //some operations
        }catch (IOException ioException){
            //some code
        }
    }

But what if I have a class that takes a reference of already instantiated FileWriter? Then I get a problem. I think I have a big "hole" in this use-case. Can someone point what am I missing? I tried doing this:

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
        }
    }
} 

My only goal was ("as I am lazy") to automatically close the resource using its reference. Unfortunately, it didn't quite work. How to better understand why I get quoted warning?

标签: javaresourcestry-catch-finallytry-with-resources

解决方案


You can use try with resources for any resources created outside the try block if you declare a new variable for the scope of the try block. Change m1 to:

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

This works in Java 9 onwards. A local variable in try clause is required so that there is no ambiguity in case fileWriter was changed inside the block - see JDK-7196163.


推荐阅读