有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java嵌套或顺序异常处理?

我想这不一定有一个“正确”的答案,也许这更像是一个风格的问题,但我经常发现自己想知道如何构造try/catch块

例如,以我下面假设的代码中概述的两个方法(纯粹是说明性的)为例,我有一个方法抛出我多次调用的异常,但根据调用的不同需要不同的处理。类似地,可能会使用不同的处理程序引发不同类型的异常

private Object exceptionMethod() throws Exception {
    throw new Exception("Something bad happened");
}

public void useMethodSequentialHandlers() {
    Object o1; // Must be declared in a wider scope than where it is used
    try {
        o1 = exceptionMethod();
    } catch (Exception ex) {
        // Assume we cannot continue after this exception so we'll return or
        // rethrow to exit the method
        return;
    }

    Object o2; // Must be declared in a wider scope than where it is used
    // Do something that requires o1
    for (int i = 0; i < 100; i++) {
        try {
            o2 = exceptionMethod();
            // Here we would use the objects in some manner
            boolean equal = o1.equals(o2);// Just a pointless example
                                                // to show that both objects
                                                // are required
                // Assume the method does a load of stuff down here
        } catch (Exception ex) {
            // Assume we can continue to the next iteration after this exception
            continue;
        }
    }
}

在我看来,按顺序排列try/catch块的优点是读者更清楚地知道我在什么时候响应异常,因此代码可能更清晰。 缺点是,我们在方法中的各个地方都有异常处理,并且我们在比所需范围更广的范围内声明了变量(这是一件坏事吗?)

或者:

public void useMethodNestedHandlers() {
    try {
        Object o1 = exceptionMethod(); // Can be declared inside scope where it is used
        // Do something that requires o1
        for (int i = 0; i < 100; i++) {
            try {
                Object o2 = exceptionMethod(); // Can be declared inside scope where it is used
                // Here we would use the objects in some manner
                boolean equal = o1.equals(o2); // Just a pointless example
                                                // to show that both objects
                                                // are required
                // Assume the method does a load of stuff down here
            } catch (Exception ex) {
                // Assume we can continue to the next iteration after this
                // exception
                continue;
            }
        }
    } catch (Exception ex) {
        // Assume we cannot continue after this exception so we'll return or
        // rethrow to exit the method
        return;
    }
}

在这里,我们将异常处理逻辑放在一起,并在使用的范围内声明变量。然而,对我来说,异常处理逻辑似乎不太清楚,因为它离它的起点更远。 有没有人对哪一个更好有意见,或者我只是在担心毫无意义的细节,应该继续我的工作?:-)

谢谢


共 (4) 个答案

  1. # 1 楼答案

    代码应该是1)正确的,2)可读的。通常,所有不可恢复的异常都应该在应用程序的最高层处理(或者根本不处理)。这意味着它们应该正确地显示给用户。所有可恢复异常应尽可能“高”处理。我建议使用尽可能少的try-catch语句

  2. # 2 楼答案

    我宁愿两者都视情况而定

    案例1

      Object obj;
       try {
         // do something 
      } catch (Exception e) {
            obj = default_obj; // assign default object
      }
    
       try {
          // do something either with specific or default object
       } catch (Exception e) {
           // handle exception
       }
    

    在这里,即使第一次尝试捕获失败,也可以使用默认值继续操作

    案例2

    try {
        Object obj; 
         // acquire object
    
        // do something only if acquire object is successful
    } catch (Exception e) {
       // handle exception
    }
    

    当获取对象未成功时,此处不再继续

    在这里,处理异常的方法更像是一种必要而不是一种风格

  3. # 3 楼答案

    我相信,在所有情况下,答案都不是从技术分析中得出的,我们应该忽略最初的开发工作,研究代码的未来

    为此,我建议将第一种方法作为最佳选择,除非有真正的技术理由选择第二种方法

    总之:

    < EM >如果两个样式之间没有<强>技术> /强>差异,请考虑将来的代码读取器,并使其尽可能明显地<<强> >。eem>

  4. # 4 楼答案

    异常的美妙之处在于,您不必在异常发生的地方处理它们。这就是为什么你实际上应该使用你的第二种风格,但是没有外部的try-catch

    public void useMethodNestedHandlers() {
        Object o1 = exceptionMethod(); // Can be declared inside scope where it is used
        // Do something that requires o1
        for (int i = 0; i < 100; i++) {
            try {
                Object o2 = exceptionMethod(); // Can be declared inside scope where it is used
                // Here we would use the objects in some manner
                boolean equal = o1.equals(o2); // Just a pointless example
                                                // to show that both objects
                                                // are required
                // Assume the method does a load of stuff down here
            } catch (Exception ex) {
                // Assume we can continue to the next iteration after this
                // exception
                continue;
            }
        }
    }
    

    为快乐日场景编写代码,让其他人担心失败。这就是实现关注点分离的方法:通常所有故障都由同一段代码处理,过早捕获会导致重复代码