当我在此方法中的块return内的两个值中都出现资源泄漏警告时,我在 Eclipse 中正常工作:try
@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;
}
我不明白它是如何导致资源泄漏的,因为我reader在范围之外声明变量,在块try内添加资源并在块中使用另一个来try关闭它以忽略异常并且if出于某种原因......finallytry...catchNullPointerExceptionreadernull
据我所知,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);
}
结果是:
calling test()
try block
finally block
test() returned b
知道了这一切,为什么 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;
}