将资源移出试用版

Posted

技术标签:

【中文标题】将资源移出试用版【英文标题】:Move resource out of try-with 【发布时间】:2020-09-11 09:30:08 【问题描述】:

我想创建一个包装资源的类实例。问题:当构造函数抛出时,资源就丢失了。我正在尝试为此找到解决方案。 Try-with-resource 是一个看起来不错的构造,但我无法将资源移出它。

例如,包装了 HTTP 客户端的服务客户端:

class ServiceClient implements Closeable 
  ServiceClient(ClosableHTTPClient client)  /* ... */ 
  public close()  client.close() 

  public ServiceClient create(String url) throws IOException 
    try (ClosableHTTPClient client = createHttpClient(url)) 
      return new ServiceClient(client);
      // make try-with do not close `client` on success
  

  public ClosableHTTPClient createHttpClient(String url) 
    return HttpClientBuilder.create()
        .setConnectionManager(createClosableConnectionManager()) // must be closed, when `build` throws 
        .build();
  

【问题讨论】:

您当前的伪代码没有意义。到create 完成时,它创建的东西包含一个已关闭客户端的包装器。 Try-with-resources 是在资源完成时总是 关闭资源的东西。这似乎是你想要的相反。但是我不认为我理解你的问题 @Michael 这是我的问题:我希望它只在存在异常时关闭它。 【参考方案1】:

构造函数抛出异常。

class Foo implements AutoClosable 

    private final Bar someResource;

    /**
     * @param someResource whose ownership is taken over.
     */
    Foo(Bar someResource) 
        this.someResource = someResource;
        try 
            ...
         catch (Throwable e) 
            someResource.close(); // If this.close is not final.
            throw e;
        
    

    @Override public void close()  someResource.close(); 
    ...

唯一的解决方案是处理构造函数中抛出的任何异常。 事件标准 java 类有时会忘记(负容量的 BufferedReader 不会关闭其包装的阅读器)。

【讨论】:

以上是关于将资源移出试用版的主要内容,如果未能解决你的问题,请参考以下文章

.NET 6新特性试用 | Controller支持IAsyncDisposable

试用资源大为innojoy专利搜索引擎系统

数字资源e点通|申报大公报全文检索数据库试用通知

使用 MATLAB 试用版将 MATLAB GUI 转换为 .exe

数据库信息鼎秀古籍全文检索平台开通试用

数据库试用鼎秀古籍全文检索平台试用通知