如何正确使用guava Closer

时间:2016-09-23 10:02:40

标签: java exception-handling lucene guava

我正在努力弄清楚如何使用guava库中的Closer实用程序。请参阅下面的代码。

  • 有一件事是IndexWriter在对象初始化和IOException上抛出close()。因此,finally和rethrow块中的代码带有下划线。
  • 另一个问题是,为什么我必须抓住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);
}

`

非常感谢

(坚持使用Java 6)

1 个答案:

答案 0 :(得分:4)

Guava's own explanation开始,您 使用Throwable,是的。

这是他们的示例代码段:

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();
  }
}

请注意,它们会抓取Throwable并直接从Closer实例重新抛出它。

至于为什么Throwable而不是,我们说IOExceptionRuntimeException,因为Closer 必须知道发生了错误,因此可以正常关闭资源。一切只是做正确的事情。因此,如果你做得不好,它可以工作,但不能保证。

不是说,如果您的方法可以抛出MyOwnCheckedException,例如,您必须声明它们:

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

Java 7示例,用于比较:

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

如果将Closer示例与Java 7示例进行比较,您可以看到我仍然需要在方法签名中声明IOException

对于您的情况,这是您必须要做的:

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;
  }
}

为避免尝试金字塔,请执行以下操作:

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();
  }
}