このメソッドのブロック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
スコープ外で宣言し、ブロック内にリソースを追加し、他のブロックを使用して例外を無視し、ifをブロック内try
で閉じているため、リソースリークがどのように発生するのかわかりません...finally
try...catch
NullPointerException
reader
null
私が知っていることから、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
このすべてを知っているのに、ブロックResource leak: 'reader' is not closed at this location
内でEclipseを閉じているかどうかをEclipseが教えてくれるのはなぜですか?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;
}