Java 允许您创建一个全新的子类型Throwable
,例如:
public class FlyingPig extends Throwable { ... }
现在,很少,我可能会做这样的事情:
throw new FlyingPig("Oink!");
当然还有其他地方:
try { ... } catch (FlyingPig porky) { ... }
我的问题是:
- 这是一个坏主意吗?如果是这样,为什么?
- 如果这是一个坏主意,可以做些什么来防止这种子类型化?
- 由于它是不可预防的(据我所知),可能会导致什么灾难?
- 如果这不是一个坏主意,为什么不呢?
- 你怎么能做出有用的事情
extends Throwable
呢?
- 你怎么能做出有用的事情
提议的场景#1
我真的很想做这样的事情的场景具有以下属性:
- “事件”是最终会发生的事情。预计。_ 它绝对不是一个,而且它什么时候发生
Error
也没有-al 。Exception
- 因为在意料之中,所以会有一个
catch
等待。它不会“溜走”任何东西。它不会“逃避”任何对catch
一般Exception
和/或Error
.
- 因为在意料之中,所以会有一个
- “事件”很少发生。
- 当它发生时,通常会有很深的堆栈跟踪。
所以也许现在我想说的很清楚:FlyingPig
是穷举递归搜索的结果。
要搜索的对象是存在的:只要在搜索空间的大海中找到它。搜索过程将是一个漫长的过程,因此异常处理相对昂贵的成本可以忽略不计。事实上,使用boolean isFound
标志的传统控制流构造替代方案可能更昂贵,因为它必须在整个搜索过程中不断检查,很可能在递归的每个级别。此检查将在 99.99% 的情况下失败,但传播终止条件是绝对必要的。在某种程度上,虽然有效,但检查效率低下!
通过在找到所寻找的对象时简单地throw
-ing a FlyingPig
,您不必将代码与boolean isFound
标志的管理混为一谈。不仅在这方面代码更干净,而且由于这个遗漏它可能运行得更快。
总而言之,选择是在这两者之间:
- 传统的控制流方法
- 使用 a
boolean isFound
,连续检查 - 99.99% 的时间,支票是一种“浪费”,因为它仍然是
false
- 当它最终变成 时
true
,你停止递归,你必须确保你可以正确地放松到最初的调用。
- 使用 a
FlyingPig
方法- 不要打扰任何
boolean isFound
. - 如果找到,就
throw new FlyingPig()
; 这是预期的,所以会有一个catch
。 - 没有
boolean
标志管理,如果你需要继续前进,没有浪费的检查,没有手动展开递归的簿记等。
- 不要打扰任何
问题:
- 这种(ab)使用异常的技术是否有效?(有名字吗?)
- 如果有效,应该
FlyingPig extends Throwable
,还是Exception
很好?(即使它的情况没有什么特别的?)