简体   繁体   English

如何正确使用番石榴关闭器

[英]How to use guava Closer properly

i'm struggling to figure out how to use the Closer utility from the guava library. 我正在努力弄清楚如何使用番石榴库中的Closer实用程序。 Please see the code below. 请参见下面的代码。

  • One thing is, that the IndexWriter throws an IOException on both object initialization and close() . 一件事是, IndexWriter在对象初始化和close()上都抛出IOException Therefore, the code in the finally and rethrow blocks is underlined. 因此,在finally和rethrow块中的代码带有下划线。
  • The other question is, why do i have to catch Throwable instead of other exception types and do i have to rethrow the errors (i would prefer to log those at the spot) 另一个问题是,为什么我必须捕获Throwable而不是其他异常类型,并且必须重新抛出错误(我希望现场记录这些错误)

` `

int getDocumentsCount() {
    Closer closer = Closer.create();
    try {
        IndexWriter iwriter = closer.register(openIndexWriter());
        return iwriter.numDocs();
    } catch (Throwable e) {
        logger.error(e, e);
        return -1;
    } finally {
        closer.close();
    }
}


IndexWriter openIndexWriter() throws IOException {
    return new IndexWriter(directory, analyzer, false,
        IndexWriter.MaxFieldLength.UNLIMITED);
}

` `

Thanks a lot 非常感谢

(stuck with Java 6) (卡在Java 6中)

From Guava's own explanation , you have to use Throwable , yes. 根据番石榴自己的解释 ,您必须使用Throwable ,是的。

Here's their example snippet: 这是他们的示例片段:

public void foo() throws IOException {
  Closer closer = Closer.create();
  try {
    InputStream in = closer.register(openInputStream());
    OutputStream out = closer.register(openOutputStream());
    // do stuff with in and out
  } catch (Throwable e) { // must catch Throwable
    throw closer.rethrow(e);
  } finally {
    closer.close();
  }
}

Note that they catch Throwable and rethrow it directly from the Closer instance. 请注意,它们捕获Throwable并直接从Closer实例将其重新抛出。

As to why it is Throwable and not, let's say IOException or RuntimeException , it's because the Closer must know that an error occurred so that it can close the resources properly. 至于为什么它是Throwable而不是Throwable原因,比如说IOExceptionRuntimeException ,这是因为Closer 必须知道发生了错误,以便可以正确关闭资源。 All is only a matter of doing things proper. 一切只是做正确的事。 So it can work if you don't do it properly, but it's not guaranteed. 因此,如果操作不正确,它可以正常工作,但不能保证。

Not that if your method can throw MyOwnCheckedException , for instance, you have to declare them: 并不是说,如果您的方法可以引发MyOwnCheckedException则必须声明它们:

} catch (Throwable t) {
  throw closer.rethrow(e, MyOwnCheckedException.class);
} finally {
  closer.close();
}

Java 7 example, for comparison: Java 7示例,用于比较:

public void foo() throws IOException {
  try (InputStream in = openInputStream();
       OutputStream out = openOutputStream();
    // do stuff with in and out
  }
}

If you compare the Closer example with the Java 7 example, you can see that I still have to declare the IOException in the method signature. 如果将Closer示例与Java 7示例进行比较,可以看到我仍然必须在方法签名中声明IOException


For your case, this is what you have to do: 对于您的情况,这是您必须要做的:

int getDocumentsCount() {
  try {
    Closer closer = Closer.create();
    try {
       IndexWriter iwriter = closer.register(openIndexWriter());
      return iwriter.numDocs();
    } catch (Throwable e) {
      closer.rethrow(e);
    } finally {
      closer.close();
    }
  } catch (IOException e) {
    logger.error(e, e);
    return -1;
  }
}

To avoid try-pyramids, I'd do the following: 为了避免尝试金字塔,我将执行以下操作:

int getDocumentsCount() {
  try {
    return doGetDocumentsCount();
  } catch (IOException e) {
    logger.error(e, e);
    return -1;
  }
}

int doGetDocumentsCount() throws IOException {
  Closer closer = Closer.create();
  try {
    IndexWriter iwriter = closer.register(openIndexWriter());
    return iwriter.numDocs();
  } catch (Throwable e) {
    closer.rethrow(e);
  } finally {
    closer.close();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM