通过以不同方法处理异常来进行代码重构

时间:2018-12-02 16:21:28

标签: java exception-handling

我在一个类中有以下两种方法

// 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种具有相同捕获类型的方法,这将变得更加乏味。

如果您使用不同的方法来处理此类情况,请提出建议。

2 个答案:

答案 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中再次处理此非特定的异常。