我想知道如何处理异常并仍然避免重复代码。以下是我对处理这种情况的看法。
重复代码避免情况(我不喜欢在这里使用instanceof)。
try{
//some code which might throw multiple different exceptions.
} catch(Exception e) {
//do something here
if(e instanceof IOException) {
// do something only when this type exception occurred.
} else if( e instanceof SQLException){
// do something only when this type of exception occurred.
} else if( e instanceof SomeCustomExceptionMaybe){
// do something only when this type of exception occurred.
}
//continue exception handling here.
}
VS
没有实例(我真的不喜欢有重复的代码)。
try{
//some code which might throw multiple different exceptions.
} catch(IOException e1) {
// The order must always be this.
// do something general for each exception
// do something only with this exception
// do something general again.
} catch(SomeCustomExceptionMaybe e2) {
// The order must always be this.
// do something general for each exception
// do something only with this exception
// do something general again.
} //and so on
ps:在给出答案时尽量避免使用java 7异常处理:
catch(IOException | SomeOtherTypeException | AnotherTypeException)
编辑:我没有使用java 7,这就是为什么我要求避免基于java 7的响应。
答案 0 :(得分:2)
像第一个例子中那样捕获原始Exception
是一个非常糟糕的解决方案。
Exception
是应检查和处理的已检查异常(IOException
等)的父类;但对于RuntimeException
来说,这也是信号编程错误(没有检查参考无效或数组索引等)的信号,通常不会被捕获 - 而是更正。
此外,当Exception
块中的代码稍后被修改并抛出新的异常时,捕获非常宽泛的try
可能会产生一些意想不到的副作用:它们将被现有的静默捕获catch
阻止。
因此,我认为为每种不同类型的异常设置一个独特的catch
块会好得多,即使它意味着复制(在Java7之前)一些错误处理代码。
当然,限制此代码重复的最明显方法是使用常用方法将其外部化:
try {
...
} catch (FooException fe) {
handleException(fe);
} catch (BarException be) {
handleException(be);
}
...
private void handleException(Exception e) {
...
}
如果严格按照相同的方式处理所有异常,那就没关系。但是,只要您想根据确切的异常类型执行不同的操作,就需要使用instanceof
运算符,这种运算符始终具有很强的代码味道。
总之,我会将错误处理代码保留在catch
块中,即使它现在意味着一些代码重复 - 从长远来看它仍然会更强大。
答案 1 :(得分:2)
第一个明显的解决方案是使用方法:
catch(IOException e1) {
doSomethingGeneral();
// do something only with this exception
doSomethingGeneralAgain();
}
虽然留下了一些重复。以冗长为代价,因为Java还没有lambdas(但是在Java 8中),你可以在一些匿名类中提取特定的行为:
catch(IOException e1) {
handleException(new Runnable() {
@Override
public void run() {
// do something only with this exception
}
});
}
其中handleException()的工作方式如下:
private void handleException(Runnable specificBehavior) {
// do something general
specificBehavior.run();
// do something general again
}
我迫不及待地等待Java 8,这将允许重写为:
catch(IOException e1) {
handleException(() -> {
// do something specific
});
}
答案 2 :(得分:0)
我还没有测试过以下方法,但也许有帮助:
try{
//some code which might throw multiple different exceptions.
} catch(Exception e) {
if ((e instanceof IOException) || (e instanceof SomeCustomExceptionMaybe)) {
//do something
} else {
}
}