我在一个类中有以下两种方法
// this method doesn't return anything.
void X(){
try{operation1}
catch(SpecificException1 e1){do something}
catch(SpecificException2 e2){do something}
catch(SpecificException3 e3){do something}
}
// this method return an object.
Object Y(){
try{operation2}
catch(SpecificException1 e1){do something}
catch(SpecificException2 e2){do something}
catch(SpecificException3 e3){do something}
return object;
}
我尝试通过以下方式对其进行重构:
// this method doesn't return anything.
void X(){
try{operation1}
catch(Exception e){handle(e)}
}
// this method return an object.
object Y(){
try{operation2}
catch(Exception e){handle(e)}
return object;
}
handle(Exception e){
try{ throw e}
catch(SpecificException1 e1){do something}
catch(SpecificException2 e2){do something}
catch(SpecificException3 e3){do something}
catch(Exception e){do something}
}
但是我告诉我捕获通用异常不是一种好的代码习惯,因为我在方法X和Y中捕获通用异常。但是,按照我的思考过程,尽管我在X和Y方法中捕获通用异常,但是我正在处理特定的捕获特定异常的“处理”方法中的异常。
我无法弄清楚这种方法有什么问题。在我看来,这将增加代码的可读性。在单个方法中执行相同的捕获操作将使代码的可读性降低。如果我在类中有3-4种具有相同捕获类型的方法,这将变得更加乏味。
如果您使用不同的方法来处理此类情况,请提出建议。
答案 0 :(得分:2)
更好的解决方案是定义一个通用的Command接口并将其传递给执行该命令并处理异常的方法:
public interface Command<R> {
R execute() throws SpecificException1, SpecificException2, SpecificException3;
}
...
public void x() {
this.execute(() -> operation1());
}
public SomeObject y() {
return this.execute(() -> operation2()).orElse(someDefaultValue);
}
private <R> Optional<R> execute(Command<R> command) {
try {
return Optional.ofNullable(command.execute());
}
catch(SpecificException1 e) {
doSomething();
}
catch(SpecificException2 e) {
doSomethingElse();
}
catch(SpecificException3 e) {
doYetAnotherThing();
}
return Optional.empty();
}
当然,这应该适合您的实际用例。我觉得忽略异常很奇怪。如果您确实想传播它们,则不需要此可选的内容,并且每种异常处理方法都将仅抛出例如运行时异常。
答案 1 :(得分:0)
如果引发异常,则可以捕获或引发异常。 除了缺少的“;”这不会编译,因为您的句柄方法会抛出一个未由任何catch块忽略的非特定异常。
要执行此操作,您必须为一个未指定的异常添加一个catch块,但是随后您还将吞下任何其他异常。
另一种方法是声明该句柄引发Exception,但是随后您必须在方法X和Y中再次处理此非特定的异常。