2

所以 Java 7 有一个漂亮的特性可以自动关闭一个AutoCloseable类。如果我有Bar实现Closeable(这反过来扩展AutoCloseable),并且有办法Bar从 a打开Foo,我可以这样做:

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

...并且bar会自动关闭,就像放在一个finally子句中一样。迷人的。

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

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 自动关闭我的资源,但想决定何时打开它,这可能不一定是在我获取资源的那一刻。

4

2 回答 2

1

一个想法

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

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

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

另一个想法

或者只上两节课。一个保存状态信息,直到您想要打开它。然后是您从第一个创建的另一个,它确实打开了。(有点像 aFile和 an FileInputStream。)

BarInfo barInfo = foo.getBarInfo();
...
try (Bar bar = barInfo.open()) {
   // do stuff with it
}
于 2013-04-30T20:38:07.687 回答
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(). 不幸的是,如果您等到稍后再打开它,这仍然不允许您进行自动资源管理,但也许这种方法将满足一个常见的用例,同时仍然允许灵活性。

于 2013-04-30T20:48:05.937 回答