2013-02-15 136 views
3

Eclipse(Juno)说在本示例中有资源泄漏警告。 这有效吗?
当异常发生点在for循环中时发生。资源警告java

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(); 
     } 
    } 
} 
+0

什么是* exact *错误信息? – 2013-02-15 02:40:34

+0

资源泄漏:在此位置'f'未关闭 – user2074126 2014-04-09 08:33:59

回答

1

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

我有一个关于你的代码中的唯一评论是:

  1. 这将是更容易阅读,如果你包括关键字和开/关括号之间的空间。

  2. 你不应该扔掉IOException异常finally块,而你应该记录它,并继续(如您目前)。当清理代码抛出异常和宗教记录时会发生奇怪的错误,这将为您节省极其痛苦的调试会话。

  3. 对于这样的演示,打印堆栈跟踪是好的,但一般而言,您应该记录它,只有打印短错误信息到stderr。当用户看到堆栈时,用户恐慌,即使是良性的。

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

1

当你抛出一个新的RuntimeException,你立即导致catch块没有机会关闭你的FileWriter。在投掷RuntimeException的情况下,您需要关闭您的FileWriter

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) { 
     } 
    } 
} 
+1

相反,他在try/catch语句中使用try/finally语句。所以文件将被关闭。没有资源泄漏;并且在一个非常重要的例子中,保持文件清理更接近文件使用情况,这与您的建议相比并不重要。 – Recurse 2013-02-15 02:46:02

+0

这是很好的可读性,带嵌套try的OP让我们有点难看 – AlexWien 2013-02-15 03:16:59

2

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

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

问题是println

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

你和我知道,这个“不可能发生” ......但在Eclipse代码分析器可能不明白的System.err特殊性。

而且,有可能在代码的其他地方我们做了一些导致System.err.println(...)失败;例如我们可能使用System.setErr(...)来替换正常System.err实例与一些自定义PrintWriter子类的实例,该实例在每个月的第2个周二抛出未经检查的异常。

尝试删除printlnclose调用后移动它。