java - 手动打开 Java 7 自动管理的资源

标签 java java-7 resource-management

所以 Java 7 有一个漂亮的功能,可以自动关闭 AutoCloseable 类。如果我有 Bar 实现 Closeable(它又扩展了 AutoCloseable),并且有办法打开 BarFoo,我可以这样做:

try(Bar bar=foo.openBar())
  //do something
}

...和 ​​bar 将自动关闭,就像将其放在 finally 子句中一样。可爱。

但是如果我想获得一个Bar 并稍后打开它怎么办?因为也许 Bar 就像一个 File 并且仅仅标识一个资源;我可能想识别其中的很多,但只在必要时才打开它们。

Bar bar=foo.getBar();
try(bar.open())  //doesn't work
  //do something
}

但是 Java 7 自动管理方法要求我在 try 子句中分配一个变量,不是吗?

所以也许我可以聪明一点,让 Bar.open() 返回 this(即 Bar 实例),这样我就可以这样做:

try(Bar bar=foo.getBar().open())
  //do something
}

这个功能如我所愿,但它给了我一个警告,中间 Bar 实例永远不会关闭。

也许我可以这样做:

Bar bar=foo.getBar();
try(Bar temp=bar.open())
  //do something
}

这也按照我想要的方式运行,但除了丑陋之外,我仍然收到警告 --- 这次第一个 bar 变量永远不会关闭。

所以也许我可以将 bar.open() 调用放在 protected block 中,如下所示:

try(Bar bar=foo.getBar())
  bar.open();
  //do something
}

这将按照我想要的方式工作——大多数时候。但是,如果 bar.open() 抛出异常怎么办? Java 7 将尝试关闭 bar,在我的实现中,它会抛出一个 IllegalStateException,因为您无法关闭从未打开过的东西。所以它应该,对吧?因为如果有人试图在 Bar 实例打开之前将其关闭,就会出现问题,我们需要一种快速失败的方法,而不是让问题在未知时间传播和浮出水面。

但也许我真的想要使用自动资源管理,所以我考虑放宽 Bar.close() 以便您可以随时关闭它,甚至如果您还没有打开 Bar。但现在看看我在做什么:我正在改变我的 API(可以说是让它变得更差)只是为了使用一些语法编译器糖!!

还有其他想法吗?我想使用 Java 7 自动资源管理,以便 Java 7 自动关闭我的资源,但想决定何时打开它,这不一定是我获取的那一刻 资源。

最佳答案

一个想法

让它关闭两次并执行此操作怎么样:

try (Bar bar=foo.getBar()) {
  try(bar=bar.open()) {
    //do something
  }
}

这仍然很丑陋,您必须编写一些代码才能使糖起作用。

另一个想法

或者只有两个类。一个保存状态信息,直到你想打开它。然后是您从第一个开始创建的另一个,它确实打开了。 (有点像 FileFileInputStream。)

BarInfo barInfo = foo.getBarInfo();
...
try (Bar bar = barInfo.open()) {
   // do stuff with it
}

关于java - 手动打开 Java 7 自动管理的资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16308446/

相关文章:

需要 Java Singleton 解释

generics - 用于处理泛型参数的 JDK 接口(interface)

c++ - 理解术语和概念的含义——RAII(Resource Acquisition is Initialization)

c++ - 5 法则(对于构造函数和析构函数)是否过时了?

java - 如何检查文件系统是否支持 Java 中的链接和符号链接(symbolic link)

java - 释放Java 8中打开的连接

java - 如何将数字数组中的某个数字相加?

java - 更新 Java 中的属性文件

macos - 如何修复 JEdit 5.1.0 以免提示 Java SE 6?