我如何使用Google Guava的Throwables.propagateIfInstanceOf()?

时间:2011-02-23 11:44:14

标签: java guava

The javadoc example

  try {
    someMethodThatCouldThrowAnything();
  } catch (IKnowWhatToDoWithThisException e) {
    handle(e);
  } catch (Throwable t) {
    Throwables.propagateIfInstanceOf(t, IOException.class);
    Throwables.propagateIfInstanceOf(t, SQLException.class);
    throw Throwables.propagate(t);
  }

不是很具体。真正的程序会是什么样子?我并不真正理解方法Throwables.propagateIfInstanceOf(Throwable, Class)propagate()propagateIfPossible()的目的。我什么时候使用它们?

3 个答案:

答案 0 :(得分:15)

这些方法的目的是提供一种处理已检查异常的便捷方法。

Throwables.propagate()是将已检查异常包含在未经检查的异常中的常用习惯用法的简写(以避免在方法的throws子句中声明它。)

Throwables.propagateIfInstanceOf()用于转发已检查的异常,如果它们的类型在方法的throws子句中声明的话。

换句话说,有问题的代码

public void doSomething() 
    throws IOException, SQLException {

    try {
        someMethodThatCouldThrowAnything();
    } catch (IKnowWhatToDoWithThisException e) {
        handle(e);
    } catch (Throwable t) {
        Throwables.propagateIfInstanceOf(t, IOException.class);
        Throwables.propagateIfInstanceOf(t, SQLException.class);
        throw Throwables.propagate(t);
    }  
}

是以下代码的简写:

public void doSomething() 
    throws IOException, SQLException {

    try {
        someMethodThatCouldThrowAnything();
    } catch (IKnowWhatToDoWithThisException e) {
        handle(e);
    } catch (SQLException ex) {
        throw ex;
    } catch (IOException ex) {
        throw ex;
    } catch (Throwable t) {
        throw new RuntimeException(t);
    }  
}

另见:

答案 1 :(得分:2)

我已经阅读了Guava Throwables的文档,但我发现它们并没有真正有用。使用throw new RuntimeException(e)比Throwables.propagate()更容易理解,在你想要抛出一个包含已检查异常的未经检查的异常的场景中。

答案 2 :(得分:0)

我可以为任何发现这个有用的人提供的一个场景是,如果你有一个方法包装任何抛出的异常,那么这可以用来将原因解包/转换为特定的异常。

示例:Guava的LoadingCache中的get方法将所有已检查的异常包装到ExecutionException中。文档指出可以使用getCause()检查异常。

如果我们知道{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "ec2:CreateNetworkInterface", "ec2:DescribeNetworkInterfaces", "ec2:DetachNetworkInterface", "ec2:DeleteNetworkInterface"], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets", "s3:ListBucket", "s3:GetBucketLocation", "s3:GetObject", "s3:PutObject"], "Resource": "arn:aws:s3:::*" }, { "Action": "lambda:*", "Effect": "Allow", "Resource": "arn:aws:lambda:*" }] } 将抛出这些异常(可能特定于LoadingCache,但是如果值是错误的,则缓存,Throwables.propagateIfInstanceOf可用于为调用方法处理特定异常尝试加载一个可以抛出已检查异常的值。)

cache.get()