我在
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;
}
我不明白它会如何导致资源泄漏,因为我在try范围之外声明了reader变量,在try块中添加了一个资源,并在finally块中使用其他try … catch来关闭它以忽略异常和如果读者由于某种原因为空,则为NullPointerException …
据我所知,最后块总是在离开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告诉我资源泄漏:如果我在我的finally块中关闭它,’读者’在这个位置没有关闭?
回答
我只是添加到this answer他是正确的,如果新的BufferedReader抛出异常,FileReader的一个实例将在垃圾收集器销毁时打开,因为它不会被分配给任何变量而且finally块不会关闭它因为读者会是空的.
这是我修复这个可能泄漏的方法:
@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;
}