嵌套或顺序异常处理?

时间:2012-10-11 11:49:54

标签: java exception-handling coding-style scope

我猜这里没有一个“正确”的答案,也许这更像是一种风格问题,但我常常想知道如何构建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 个答案:

答案 0 :(得分:1)

我相信在所有情况下,技术分析都没有明确的答案,应该忽略最初的开发工作并研究代码的未来。

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

总结:

如果两种样式之间没有技术差异,请考虑代码的未来读者,并使其尽可能明显 < / p>

答案 1 :(得分:1)

例外的美妙之处在于,您不必处理它们。这就是为什么你实际上应该使用你的第二种风格,但没有外部试用

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;
        }
    }
}

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

答案 2 :(得分:0)

我希望两者都取决于条件。

案例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 :(得分:0)

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