首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >手动打开Java 7自动管理的资源

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

Stack Overflow用户
提问于 2013-04-30 20:28:39
回答 2查看 75关注 0票数 2

所以Java 7有一个很棒的特性,可以自动关闭一个AutoCloseable类。如果我有Bar实现Closeable (这反过来扩展了AutoCloseable),并且有一种方法从Foo获得一个开放的Bar,我可以这样做:

代码语言:javascript
复制
try(Bar bar=foo.openBar())
  //do something
}

...and bar将自动关闭,就像它放在finally子句中一样。可爱的。

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

代码语言:javascript
复制
Bar bar=foo.getBar();
try(bar.open())  //doesn't work
  //do something
}

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

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

代码语言:javascript
复制
try(Bar bar=foo.getBar().open())
  //do something
}

这是我想要的函数,但是它给了我一个警告:中间Bar实例从未关闭过。

所以也许我能做到:

代码语言:javascript
复制
Bar bar=foo.getBar();
try(Bar temp=bar.open())
  //do something
}

这也是我想要的功能,但除了丑得要命之外,我还收到一个警告--这一次,第一个bar变量永远不会关闭。

所以也许我可以将bar.open()调用放在受保护的块中,如下所示:

代码语言:javascript
复制
try(Bar bar=foo.getBar())
  bar.open();
  //do something
}

这将是我想要的方式--大多数情况下。但是,如果bar.open()抛出异常怎么办?Java7将尝试关闭bar,在我的实现中,它将抛出一个IllegalStateException,因为您无法关闭从未打开的东西。所以应该是吧?因为如果有人试图在一个Bar实例被打开之前关闭它,那么就会出现一些问题,我们希望采用一种快速失败的方法,而不是让问题在未知的时间传播并浮出水面。

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

还有其他想法吗?我想使用Java 7自动资源管理,这样Java 7就会自动关闭我的资源,但是我想决定何时打开它,在我获得资源的时候,这可能并不一定。

EN

回答 2

Stack Overflow用户

发布于 2013-04-30 20:38:07

One idea

不如让它关闭两次然后这样做:

代码语言:javascript
复制
try (Bar bar=foo.getBar()) {
  try(bar=bar.open()) {
    //do something
  }
}

这还是很难看的,你必须写一些代码才能让糖起作用。

另一个想法

或者只上两节课。一个保存状态信息直到你想打开它的人。还有一个是你从第一个开始创建的,它真的是开放的。(有点像FileFileInputStream。)

代码语言:javascript
复制
BarInfo barInfo = foo.getBarInfo();
...
try (Bar bar = barInfo.open()) {
   // do stuff with it
}
票数 1
EN

Stack Overflow用户

发布于 2013-04-30 20:48:05

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

代码语言:javascript
复制
public Bar openBar() {
  Bar bar=getBar();
  bar.open();
  return bar;
}

这样,就可以通过调用Foo.openBar()来使用自动资源管理。

代码语言:javascript
复制
try(Bar bar=foo.openBar()) {
  //do something
}

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16308446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档