我对 OOP 方法进行了测试,并被问到以下 True\False 问题:
“为了从深度递归调用中返回而抛出异常被认为是对异常机制的合法使用”。
我认为这是错误的,因为它并不是应用程序流程中的真正异常,但我的老师将其标记为 true,并说这是从深度递归返回的快速方法。
在我看来,这类似于在处理 IndexOutofBounds 时用 try\catch 包装 for 块,这不是正确的编码。
你认为哪个是正确的?
使用异常从递归返回是错误的。例外是针对特殊情况。从递归中返回并不是一个例外情况。
来自 Java 语言教程:
Java 编程语言使用异常来处理错误和其他异常事件。
和
异常是在程序执行期间发生的事件,它破坏了正常的指令流。
这是错误的,并且违反了标准的编程实践,因为程序员希望将异常用于异常情况。任何其他用途都是错误的。时期。
在我看来,如果试图保持代码清晰,应该保留使用异常来处理错误。
但是,Caml 程序员长期以来一直使用从深度递归返回的异常来完成递归,而不必取消所有调用的堆栈(白白浪费时间)。
但是现在,递归机制(至少在 Caml 中)引入了就地递归。这意味着当调用递归函数时,如果它是终端的(调用后没有计算),那么堆栈帧将被替换而不是被添加。这意味着不再需要解除所有调用的堆栈,也不再需要使用异常来避免这样做。
所以在我看来,异常应该只用于防止错误,因为它们的其他用法现在已经过时了(至少在某些语言中)。
按照 Java 和 JVM 的规则是绝对合法的,语义清晰。然而,由于它是关于控制流的,它几乎与 OOP 无关。相同的特性可以用在不是面向对象的语言中,但碰巧有例外。
这里的关键点是合法的:如果我们说所有不被禁止或不利用未定义特性的东西都是合法的,那么当然,跳过异常是合法的。
这并不意味着:这是一种很好的做法。但是......好的做法是,大多数Java程序员都理解,这并不过分,恕我直言......
只有一件事:如果您需要经常这样做,请使用预制的用户定义异常,因为由于堆栈跟踪收集,在 Java 中创建异常对象是昂贵的。