资源警告java

时间:2013-02-15 02:28:34

标签: java eclipse resources io memory-leaks

Eclipse(Juno)表示此示例中存在资源泄漏警告。 这有效吗?
当异常抛出点位于for循环中时会发生这种情况。

package kuni;

import java.io.FileWriter;
import java.util.Arrays;

public class ResourceWarn {
    public static void main(String[] args){

        try {
            FileWriter f = null;
            try{
                f = new FileWriter("test.txt");
                for(String s : Arrays.asList("a","b","c")){
                    if(s.equals("c"))throw new RuntimeException("aa"); //resource leak warn here
                    f.write(s);
                }
            }finally{
                try{
                    f.close();
                }catch(Exception ignore){
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

我想我知道Eclipse在抱怨什么。

        } finally {
            try {
                System.err.println("closing f");
                f.close();
            } catch(Exception ignore) {
            }
        }

问题是println !!!

Eclipse认为System.err.println(...)调用可能会抛出异常。如果发生这种情况,那么f.close()电话就不会发生......这就是泄漏。

你和我知道这“不会发生”......但Eclipse代码分析器可能不了解System.err的特殊性。

此外,代码中的其他地方我们可能已经做了 导致System.err.println(...)失败的事情;例如我们可能使用System.setErr(...)将一个普通System.err实例替换为一个自定义PrintWriter子类的实例,该子类在每个月的第二个星期二抛出一个未经检查的异常。

尝试删除println或在close来电后移动它。

答案 1 :(得分:1)

不,那里没有资源泄漏。我不知道日食在抱怨什么。

我对您的代码的唯一评论是:

  1. 如果在关键字和开/关括号之间包含空格,将会更容易阅读。

  2. 你不应该在finally块中丢弃IOException,而应该记录它并继续(就像你现在一样)。当清理代码抛出异常时会发生奇怪的错误,并且虔诚地进行日志记录将为您节省极其痛苦的调试会话。

  3. 对于这样的演示,打印堆栈跟踪很好,但一般情况下应该记录它,并且只向stderr打印一条简短的错误消息。当用户看到堆栈痕迹时,即使是良性的,也会感到恐慌。

  4. 除此之外,代码对我来说看起来不错,并且以上都没有提示资源泄漏。

答案 2 :(得分:1)

当您掷出新的RuntimeException时,您会立即转到catch区块而无法关闭FileWriter。如果抛出FileWriter,您需要关闭RuntimeException

public static void main(String[] arg) {
    FileWriter f = null;
    try {
        f = new FileWriter("test.txt");
        for (String s : Arrays.asList("a", "b", "c")) {
            if (s.equals("c"))
                throw new RuntimeException("aa"); // resource leak warn here
            f.write(s);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (f != null) {
                f.close();
            }
        } catch (Exception ignore) {
        }
    }
}