手动打开Java 7自动管理资源

时间:2013-04-30 20:28:39

标签: java java-7 resource-management

因此,Java 7有一个非常好的功能,可以自动关闭AutoCloseable类。如果我Bar实施Closeable(反过来扩展AutoCloseable),并且有办法从Bar获得开放Foo,我可以做这样:

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()调用放在受保护的块中,如下所示:

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

这将以我想要的方式运作 - 大部分时间。但是如果bar.open()抛出异常呢? Java 7将尝试关闭bar,在我的实现中,它会抛出IllegalStateException,因为你无法关闭从未打开过的东西。它应该,对吧?因为如果有人试图在Bar实例被打开之前关闭它,那么我们需要一种快速失败的方法,而不是让问题在未知时间传播并浮出水面。

但也许我真的想要使用自动资源管理,因此我考虑放松Bar.close()以便您可以随时关闭它,即使您没有打开Bar。但是现在看看我正在做什么:我正在改变我的API(可以说它的劣势)只是为了使用一些语法编译器糖!!

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

2 个答案:

答案 0 :(得分:1)

一个想法

如何让它关闭两次并执行此操作:

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
}

答案 1 :(得分:0)

啊,我拥有它!我将在API中使用两种不同的方法!一个将是Foo.getBar(),它只返回一个Bar实例。第二个是Foo.openBar(),这只是一种方便的方法,首先调用Foo.getBar(),然后像这样调用Bar.open()

public Bar openBar() {
  Bar bar=getBar();
  bar.open();
  return bar;
}

这样,可以通过调用Foo.openBar()

来使用自动资源管理
try(Bar bar=foo.openBar()) {
  //do something
}

当想要稍后使用Bar实例时,可以调用Foo.getBar()。不幸的是,如果你等到以后打开它,这仍然不允许你进行自动资源管理,但是这种方法可能会满足一个常见的用例,同时仍然允许灵活性。