我正在重构一些代码以使用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); } } }
有什么办法可以使它变得更好?
刚写完问题,就开始考虑使用泛型的效用方法。然后想起了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); } }
非常好!
另请参见ThrowablesExplained,LoadingCache.getUnchecked以及为什么我们不赞成Throwables.propagate的原因。