我煮了一个类ExceptionHandler<T extends Exception, OptionalReturnType>
(见下文)以消除一些(我认为的)样板代码,这些代码使实际实现变得困惑,同时如果将来需要,仍然为显式异常处理提供一个钩子(Hook)。在大多数情况下,在我的应用程序(本质上是科学计算)中,没有从异常中恢复之类的东西——我需要记录问题以便修复它,否则我只会重新运行一次问题得到纠正。
其他人是否这样做(至少,在我的特定应用情况下)?这样做是否愚蠢(如果是,请解释一下为什么会很好)?
异常处理程序:
public abstract class ExceptionHandler<ExceptionType extends Exception,OptionalReturn> {
public abstract OptionalReturn handle(ExceptionType e);
//assorted boilerplate ExceptionHandling, e.g.:
public static <ET extends Exception> ExceptionHandler<ET, ?> swallower(final boolean printStackTrace, final String string) {
return new ExceptionHandler<ET,Object>() {
@Override public Object handle(ET e) {
if(printStackTrace) { e.printStackTrace(); }
if(string!=null && !string.isEmpty()) { System.err.println(string); }
return null;
}
};
}
public static <ET extends Exception> ExceptionHandler<ET, ?> swallower() { return swallower(false,null); }
}
示例使用(我正在削减,所以我实际上并没有写太多):
public class Getter<From> implements Function<Future<? extends From>, From> {
private ExceptionHandler<InterruptedException,?> IEH;
private ExceptionHandler<ExecutionException,?> EEH;
public static final ExceptionHandler<InterruptedException,?> IEH_SWALLOWER = ExceptionHandler.swallower(true,"Returning null.");
public static final ExceptionHandler<ExecutionException,?> EEH_SWALLOWER = ExceptionHandler.swallower(true,"Returning null.");
private Getter() { this(IEH_SWALLOWER,EEH_SWALLOWER); }
private Getter(ExceptionHandler<InterruptedException,?> IEH, ExceptionHandler<ExecutionException,?> EEH) {
this.IEH = IEH;
this.EEH = EEH;
}
public static <T> Getter<T> make() { return new Getter<T>(); }
public static <T> Getter<T> make(ExceptionHandler<InterruptedException,?> IEH, ExceptionHandler<ExecutionException,?> EEH) {
return new Getter<T>(IEH, EEH);
}
@Override public From apply(Future<? extends From> from) {
if (from==null) throw new NullPointerException("Null argument in call with Getter.");
return getter(from, IEH, EEH);
}
private static <T> T getter(Future<T> src, ExceptionHandler<InterruptedException,?> IEH, ExceptionHandler<ExecutionException,?> EEH) {
try { return src.get(); }
catch (InterruptedException e) { IEH.handle(e); }
catch (ExecutionException e) { EEH.handle(e); }
return null;
}
}
与 Guava 一起使用库来做一些令人尴尬的并行计算,并将 Futures 的实际 Iterable 转换为类似于
Iterables.transform(futureCollection,Getter.make())
的东西而不是内部类和异常处理的纠结。
最佳答案
老实说,我发现代码很难遵循和理解。满是static
这在 OO 设计中通常是一个不好的迹象,并且很难遵循泛型。
像这样更简单的东西不也可以吗?
private static <T> T getter(Future<T> src) {
try { return src.get(); }
catch (InterruptedException e) { handle( "some text"); }
catch (ExecutionException e) { handle( e ) }
return null;
}
您可以实现尽可能多的
handle
在基类(或静态实用程序类)中根据需要使用方法,并根据需要在 catch block 中使用它们。将根据签名选择方法,因此如果要打印文本,则传递字符串,如果要堆栈跟踪,则传递异常(或两者都传递)。这导致组合:handle( String msg )
handle( Exception e )
handle( Exception e, String msg )
此解决方案具有较少的
if
,这通常也是一个好兆头。但是我可能错过了一点,因为您发布的代码只是整个代码的摘录。
看看这个问题,这也是相关的:Pluggable Error Handling Strategy
编辑
如果我上面提出的解决方案对您的需要来说太简单了,这里有另外两种方法:
public class AbstractGetter<From> implements Function<Future<? extends From>, From> {
private abstract handleInterrupt( Exception e );
private abstract handleExecution( Exception e );
private static <T> T getter(Future<T> src ) {
try { return src.get(); }
catch (InterruptedException e) { handleInterrupt(e) }
catch (ExecutionException e) { handleExecution(e) }
return null;
}
}
并且您实现了对应于各种异常处理策略的 X 具体类。本质上就是 template图案。
您仍然可以使用委托(delegate),但在更粗粒度的级别上。您无需提供单独的处理程序,而是提供处理程序策略。这是strategy 的一种变体。那么图案。
public interface ErrorStrategy
{
public void handleInterrupt(Exception e);
public void handleExecution(Exception e);
}
public class Getter<From> implements Function<Future<? extends From>, From> {
ErrorStrategy handler = new DefaultErrorStrategy(). // default one
public Getter<From>()
{
}
public Getter<From>( ErrorStrategy h )
{
this.handler = h.
}
private static <T> T getter(Future<T> src ) {
try { return src.get(); }
catch (InterruptedException e) { handler.handleInterrupt(e) }
catch (ExecutionException e) { handler.handleExecution(e) }
return null;
}
}
您可以创建所需的 X 错误处理策略。
关于通过策略模式处理 Java 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2254266/