gpt4 book ai didi

java - 使用 try...finally 时发生资源泄漏?

转载 作者:搜寻专家 更新时间:2023-10-31 19:40:00 25 4
gpt4 key购买 nike

当我在 try block 内的两个 return 值中遇到资源泄漏警告时,我在 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;
}

我不明白它会如何导致资源泄漏,因为我在 try 范围之外声明了 reader 变量,在 try 中添加了一个资源 block 并在 finally block 中关闭它,使用另一个 try...catch 来忽略异常和 NullPointerException 如果 reader 由于某种原因为 null...

据我所知,finally block 总是在离开 try...catch 结构时执行,因此在 try 中返回一个值> block 在退出方法之前仍会执行 finally block ...

这很容易证明:

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

知道所有这些,如果我在 finally block 中关闭它,为什么 eclipse 会告诉我 Resource leak: 'reader' is not closed at this location


回答

我只想添加到 this answer他是对的,如果 new BufferedReader 抛出异常,FileReader 的实例将在垃圾收集器销毁时打开,因为它不会被分配给任何变量和 finally block 不会关闭它,因为 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;
}

最佳答案

从技术上讲,有一条 BufferedReader 不会关闭的路径:如果 reader.close() 会抛出异常,因为您捕获了异常但什么都不做。这可以通过在您的 catch block 中再次添加 reader.close() 来验证:

    } finally
{
try {
reader.close();
} catch (Exception e) {
reader.close();
}
}

或者删除 finally 中的 try/catch:

    } finally
{
reader.close();
}

这将使警告消失。

当然,这对你没有帮助。如果 reader.close() 失败,那么再次调用它就没有意义。问题是,编译器不够聪明,无法处理这个问题。因此,您唯一明智的做法是向该方法添加一个 @SuppressWarnings("resource")

编辑 如果您使用的是 Java 7,您可以/应该做的是使用 try-with-resources 功能。这将使警告正确,并使您的代码更简单,为您节省一个 finally block :

public boolean isValid(File file) throws IOException
{
try(BufferedReader 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;
}
}
return false;
}

关于java - 使用 try...finally 时发生资源泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15253036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com