为什么是Java’;s异常处理语句不应被视为非局部分支的一般机制?

为什么是Java’;s异常处理语句不应被视为非局部分支的一般机制?,java,exception-handling,Java,Exception Handling,阅读Herbert Schildt:完整参考第10章异常处理 异常处理提供了一种强大的机制来控制复杂的程序 具有许多动态运行时特性。重要的是要考虑尝试、投掷和接球 作为处理程序逻辑中错误和异常边界条件的干净方法。 与其他一些使用错误返回码表示失败的语言不同,Java 使用异常。因此,当一个方法可能失败时,让它抛出一个异常。这是一个清洁工 处理故障模式的方法。 最后一点:Java的异常处理语句不应被视为通用语句 非局部分支的机制。如果您这样做,它只会混淆您的代码并使其无效 很难维持 他所说的“非局

阅读Herbert Schildt:完整参考第10章异常处理

异常处理提供了一种强大的机制来控制复杂的程序 具有许多动态运行时特性。重要的是要考虑尝试、投掷和接球 作为处理程序逻辑中错误和异常边界条件的干净方法。 与其他一些使用错误返回码表示失败的语言不同,Java 使用异常。因此,当一个方法可能失败时,让它抛出一个异常。这是一个清洁工 处理故障模式的方法。 最后一点:Java的异常处理语句不应被视为通用语句 非局部分支的机制。如果您这样做,它只会混淆您的代码并使其无效 很难维持

他所说的“非局部分支”是什么意思?请用一个很好的例子来详细说明

请注意,这个问题是在coderanch上提出的,但那里的答案主要基于个人
因此,它没有给出一个基于根的答案(我无法通过那边的讨论阐明这一点)。

这里是一个本地分支的示例:

void foo() {
  if (someCondition) {
    doSomething();
  } else {
    doSomethingElse();
  }
}
分支很容易理解,对吗?之所以如此简单,是因为所有分支逻辑都是在
foo
中定义的。可以说是本地的。这意味着,将根据
someCondition
检查一个条件并选择其路径,但分支不会逃逸
foo
。只要看一下这个方法,您就知道代码流可能是什么样子

现在想想这个可读性较差的实现:

void foo() {
  if(bar()) {
    // branch is handled by bar
  } else {
    doSomethingElse();
  }
}

boolean bar() {
  if(somethingWrong) {
    return false;
  }
  doSomething();
}
这是不太可读的。但为什么呢?如果从
foo
调用方法
bar
,则控制流由
bar
处理<但是,code>bar可能会执行意外操作,并且仍然依赖
foo
来处理此意外情况。这不是一个好的做法,因为您在
foo
bar
之间分配连接的逻辑,其中一个位置的更改可能导致另一个位置的错误行为。这在某种程度上是异常在堆栈中被处理得太深时所做的。您甚至可以通过添加更多中间方法来扩展上述示例的复杂性。因此,这本书建议,保持局部分支,因为这通常更易于人类阅读和追踪,我同样认为这是一个好主意。查看上述代码的基于异常的实现,以更直观地了解这一点:

void foo() {
  try {
    bar()
  } catch(SomeException e) {
    doSomethingElse();
  }
}

boolean bar() {
  if(somethingWrong) {
    throw new SomeException();
  }
  doSomething();
}

显然,这个分布式分支比
if
-
else
语句更容易出错。

例如,使用NumberFormatException测试用户的输入是否为数字。我认为这与设置和捕获异常的计算复杂性有关,而不是更传统的流控制。但我不能详细说明,这就是为什么这是一个注释而不是答案。我认为“Java的异常处理语句不应该被视为非局部分支的一般机制”表示使用异常冒泡机制通过调用调用堆栈上的
catch
块中的其他函数来分支到其他函数(类似于使用
goto
语句进行非本地分支)。这打破了传统的控制流程,使得逻辑难以理解和维护。coderanch上的答案似乎表明了同样的事情。你确定这就是Herbert Schildt所说的非局部分支吗?或者还有更多。我只是在猜测什么会迫使我在程序中使用第二个版本(上面可读性较差的版本)?@ShirgillAnsari,因为分支中的处理非常复杂,需要自己的方法甚至类。事实上,Replace Conditional with polymorphics重构完全消除了
if
语句,并要求为不同的行为创建单独的类。@ShirgillAnsari是的,我很确定这就是它的意思。非局部分支总是考虑分布在方法之间的分支。在Java中,这只能通过异常实现。