如果在循环中抛出exception,则使用try-with-resources奇怪的“资源泄漏:流永远不会关闭”
为什么Eclipse给出了一个奇怪的“资源泄漏:zin永远不会关闭”警告以下代码,即使我使用try-with-resources
:
Path file = Paths.get("file.zip"); // Resource leak warning! try (ZipInputStream zin = new ZipInputStream(Files.newInputStream(file))) { for (int i = 0; i < 5; i++) if (Math.random() < 0.5) throw new Exception(); } catch (Exception e) { e.printStackTrace(); }
如果我在代码上修改“任何东西”,警告就会消失。 下面我列出了3个修改过的版本都没问题(没有警告)。
Mod#1:如果我从try
块中删除for
循环,则警告消失:
// This is OK (no warning) try (ZipInputStream zin = new ZipInputStream(Files.newInputStream(file))) { if (Math.random() < 0.5) throw new Exception(); } catch (Exception e) { e.printStackTrace(); }
Mod#2:如果我保留for
循环也没有警告for
但我删除了包装ZipInputStream
:
// This is OK (no warning) try (InputStream in = Files.newInputStream(file))) { for (int i = 0; i < 5; i++) if (Math.random() < 0.5) throw new Exception(); } catch (Exception e) { e.printStackTrace(); }
Mod#3:如果我在try-with-resources
之外创建InputStream
,也没有警告:
// This is also OK (no warning) InputStream in = Files.newInputStream(file); // I declare to throw IOException try (ZipInputStream zin = new ZipInputStream(in)) { for (int i = 0; i < 5; i++) if (Math.random() < 0.5) throw new Exception(); } catch (Exception e) { e.printStackTrace(); }
我使用Eclipse Kepler(4.3.1),但与Kepler SR2(4.3.2)的结果相同。
这似乎是Eclipse中的一个已知错误: [编译] [资源]循环中返回错误的资源泄漏问题(在finally块中传递资源) 。
我自己也对此感到满意,并在跟踪器上添加了我的投票。
更新:上述错误已在4.5 M7中解决。 这将包含在Eclipse 4.5(“Mars”)的最终版本中 – 该版本有望在2015-06-24发布。