使用try时资源泄漏...最终?

Jos*_*ior 5 java eclipse resources java-6 eclipse-juno

当我在此方法returntry块中的两个值中都出现资源泄漏警告时,我在Eclipse中正常工作:

@Override
public boolean isValid(File file) throws IOException
{
    BufferedReader reader = null;
    try
    {
        reader = new BufferedReader(new FileReader(file));
        String line;
        while((line = reader.readLine()) != null)
        {
            line = line.trim();
            if(line.isEmpty())
                continue;
            if(line.startsWith("#") == false)
                return false;
            if(line.startsWith("#MLProperties"))
                return true;
        }
    }
    finally
    {
        try{reader.close();}catch(Exception e){}
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

我不明白它会导致资源泄漏的原因,因为我是readertry作用域之外声明变量,在try块内添加资源,然后在另一个finally块中将其关闭以使用另一个try...catch忽略异常,而NullPointerExceptionif readernull出于某种原因...

据我所知,finally块总是在离开try...catch结构体时执行,因此在try块内返回值仍将finally在退出方法之前执行该块。

可以很容易地证明这一点:

public static String test()
{
    String x = "a";
    try
    {
        x = "b";
        System.out.println("try block");
        return x;
    }
    finally
    {
        System.out.println("finally block");
    }
}

public static void main(String[] args)
{
    System.out.println("calling test()");
    String ret = test();
    System.out.println("test() returned "+ret);
}
Run Code Online (Sandbox Code Playgroud)

结果是:

calling test()
try block
finally block
test() returned b
Run Code Online (Sandbox Code Playgroud)

知道了所有这些之后,为什么eclipse会告诉我Resource leak: 'reader' is not closed at this location是否要在我的finally区块中关闭它?


回答

我只是在回答中补充说他是正确的,如果new BufferedReader引发异常,则FileReader垃圾回收器销毁后将打开的实例,因为不会将其分配给任何变量,而该finally块不会将其关闭,因为reader它将是null

这是我修复此可能泄漏的方法:

@Override
public boolean isValid(File file) throws IOException
{
    FileReader fileReader = null;
    BufferedReader reader = null;
    try
    {
        fileReader = new FileReader(file);
        reader = new BufferedReader(fileReader);
        String line;
        while((line = reader.readLine()) != null)
        {
            line = line.trim();
            if(line.isEmpty())
                continue;
            if(line.startsWith("#") == false)
                return false;
            if(line.startsWith("#MLProperties"))
                return true;
        }
    }
    finally
    {
        try{reader.close();}catch(Exception e){
            try{fileReader.close();}catch(Exception ee){}
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

kan*_*kan 3

如果BufferedReader构造函数抛出异常(例如内存不足),则发生FileReader泄漏。