2

我需要知道做更少的尝试和做更多的捕获是否是控制通量的好方法,这在异常控制术语中非常重要。

因为在不断变化的情况下,如果出现问题,这永远不会继续!

我不是想节省代码行,我需要一些视觉上易于理解且在代码方面具有功能性的东西

Var ix;
Var iy;
Var iz;

try {
    try {
        do something ix;
    } catch (Exception ex1) {
        ex1.printStackTrace();
    }

    try {
        do something iy;
    } catch (Exception ex2) {
        ex2.printStackTrace();
    }

    do something iz;
} catch (Exception ex3) {
    ex3.printStackTrace();
}

或者

Var ix;
Var iy;
Var iz;

try {
        do something ix;
        do something iy;
        do something iz;

} catch (Exception ex1) {
    ex1.printStackTrace();
} catch (Exception ex2) {
    ex2.printStackTrace();
} catch (Exception ex3) {
    ex3.printStackTrace();
}
4

6 回答 6

10

这两个示例实际上会表现不同。在第二种情况下,如果捕获到异常,则以下do something都不会运行。首先,他们每个人都可以独立失败。

于 2013-10-17T14:29:46.397 回答
7

总是在尽可能小的和有限的范围内捕获异常;使用过于广泛的捕获,例如

} catch (Exception ex) {
// wrong. use explicit exceptions,
// e.g. catch(NullPointerException ex) instead, possibly with multicatch

或抓住太大的范围

try {
  //... tons of code
} catch (IOException ex) {
// and the exception happened WHERE?
}

本身就是一个反模式。

这件事说的,其他人说的都是对的。代码的行为会有所不同,因为嵌套的捕获实际上处理了内部遇到的异常,而不是将其传播到外部。

以这种方式完成的多个捕获例如异常(替换为例如 NullPointerException 并且想法仍然存在)

try {
  try {
    // some code
  } catch (Exception ex1) { /* stack dump or whatever */ }
} catch (Exception ex2) { /* stack dump or whatever */ }

也不会很好用,因为内部 Exception 是给定类型的每个异常的有效捕获(在这种情况下 -每个异常) - 因此任何可捕获的都不会传播到外部 try/catch 块。

另一件事(也已经说过无数次了)是您应该治愈异常,将其抛出(传播)或死于异常。简单地做一个堆栈转储就像在说“你,亲爱的先生,得了癌症”。它不会改善任何人的情况。如果你不能帮助它,请传播它。如果没有什么可以处理它,请优雅地死去(堆栈转储对于线程死去来说几乎不是一种优雅的方式......)。

还有一点要区分的是Java 的Throwable 类型,即错误与检查/未检查异常的区别。一般来说:

  • 错误应该导致线程立即终止,因为它表示严重的虚拟机/硬件错误,
  • 未经检查的异常(想到 RuntimeException)是一个非常特殊的情况,不可能或很难预测,因此通常不应包含它,而只是通过程序回退到最后一个有效执行的代码分支向用户发出信号,
  • 已检查异常是一种常见的异常情况,反过来,必须由程序员明确处理,并且不应中断程序执行。

tl; dr - 请在实际使用异常之前了解使用异常的基本原理。

进一步阅读:http ://docs.oracle.com/javase/tutorial/essential/exceptions/和http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683(第 39 项:使用仅针对异常情况的异常,第 40 条:对可恢复的条件使用受检异常,对编程错误使用运行时异常,第 41 项:避免不必要地使用受检异常,第 43 项:抛出适合抽象的异常。)

于 2013-10-17T14:36:12.973 回答
4

我会说这取决于你想要什么。您的任何异常都可以恢复吗?遇到异常后还要继续吗?这些事情决定了你如何处理异常。或者至少,我是怎么做的。

于 2013-10-17T14:30:30.633 回答
4

这两种方式在逻辑上是不同的。在第一种方式中,即使动作“ix”抛出异常,您也会尝试执行动作“iy”。第二种方式,如果动作“ix”抛出异常,那么“iy”和“iz”将永远不会被执行。

于 2013-10-17T14:29:26.033 回答
4

这是非常不同的!

在您的第一个代码中:

  • 如果 ix 触发 ex1,它将继续 iy。但是如果触发ex3,一切都会停止。
  • 如果 iy 触发 ex2,它将继续 iz。但是如果触发ex3,一切都会停止。

在您的第二个代码中:

  • 如果抛出异常,一切都会停止。

您应该阅读本教程

于 2013-10-17T14:31:59.520 回答
2

您的问题没有单一的正确答案。这取决于。正如您从其他答案中看到的那样,您的第一个和第二个代码的执行方式不同(在第二个示例中可能会跳过某些操作)。你应该专注于:

  • 您正在捕获的异常类型(这些异常是否不同,您想以不同的方式处理它们吗?),
  • 你将如何处理异常,
  • 是影响其他代码的一个例外,
  • 单个 catch 语句是否会捕获两个或多个异常,
  • 等等

您应该针对给定的情况考虑每种解决方案。

于 2013-10-17T14:40:00.820 回答