小编典典

Guava缓存并保留检查的异常

java

我正在重构一些代码以使用guava Cache

初始代码:

public Post getPost(Integer key) throws SQLException, IOException {
    return PostsDB.findPostByID(key);
}

为了不破坏某些内容,我需要按原样保留任何引发的异常,而不用包装它。

当前的解决方案看起来有些难看:

public Post getPost(final Integer key) throws SQLException, IOException {
    try {
        return cache.get(key, new Callable<Post>() {
            @Override
            public Post call() throws Exception {
                return PostsDB.findPostByID(key);
            }
        });
    } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        if (cause instanceof SQLException) {
            throw (SQLException) cause;
        } else if (cause instanceof IOException) {
            throw (IOException) cause;
        } else if (cause instanceof RuntimeException) {
            throw (RuntimeException) cause;
        } else if (cause instanceof Error) {
            throw (Error) cause;
        } else {
            throw new IllegalStateException(e);
        }
    }
}

有什么办法可以使它变得更好?


阅读 215

收藏
2020-11-13

共1个答案

小编典典

刚写完问题,就开始考虑使用泛型的效用方法。然后想起了Throwables的一些东西。是的,它已经在那里!)

可能还需要处理UncheckedExecutionException甚至ExecutionError

因此解决方案是:

public Post getPost(final Integer key) throws SQLException, IOException {
    try {
        return cache.get(key, new Callable<Post>() {
            @Override
            public Post call() throws Exception {
                return PostsDB.findPostByID(key);
            }
        });
    } catch (ExecutionException e) {
        Throwables.propagateIfPossible(
            e.getCause(), SQLException.class, IOException.class);
        throw new IllegalStateException(e);
    } catch (UncheckedExecutionException e) {
        Throwables.throwIfUnchecked(e.getCause());
        throw new IllegalStateException(e);
    }
}

非常好!

另请参见ThrowablesExplainedLoadingCache.getUnchecked以及为什么我们不赞成Throwables.propagate的原因

2020-11-13