假设我想在我的代码中为特定的“案例”设置一个未经检查的例外 - 当队列满75%时说。我只需要一个例外,说“队列达到了75%的门槛”。
一个 - 最明显的(?)方式是
public class QueueT extends RuntimeException {
QueueT () {
super("queue has reached the 75% threshold");
}
}
所有&仅用于此例外
try {
// some stuff here
throw new QueueT();
} catch (QueueT e) {
System.out.print("<<"+e+">>");
}
我想知道的是 - 通过上述方式我正在获得什么 - 写一个例外 -
而不是下面。回想一下:我没有其他用途 - 不需要 Throwable 或其他任何方法。
try {
// some stuff here
throw new RuntimeException("queue has reached the 75% threshold");
} catch (RuntimeException e) {
System.out.print("<<"+e+">>");
}
从我所看到的,我唯一的收获就是在不打扰 String 属性的情况下调用构造函数。
它甚至有收获 - 我可以轻松地参数化我将抛出异常的阈值:
// setting the percentage value here
throw new RuntimeException("queue has reached the" + percentage + "% threshold");
提前致谢。
答案 0 :(得分:2)
假设我想在我的代码中为特定的“case”设置一个未经检查的异常 - 比如当队列满75%时。我只需要一个例外,说“队列达到了75%的门槛”。
这是例外情况不佳的情况。例外不用于业务逻辑;它们用于特殊条件。这似乎是预期的场景,更像是通知而非异常。你如何期待一个抓住这个例外的人做出反应?只是忽略它?如果是这样,例外的目的是什么?此外,以这种方式使用异常根本不具备性能,因为它必须填写堆栈跟踪,并且反复执行此操作会使您的性能非常糟糕。
关于你的另一个问题,使用你自己的运行时异常与RuntimeException
的好处是你现在有了你自己的异常(希望)在语义上合适,你可以适当地抛出或处理。仅仅使用RuntimeException
本身并没有真正提供那么多信息。
答案 1 :(得分:0)
你获得的是你的第一个例子,
try {
// some stuff here
throw new QueueT();
} catch (RuntimeException e) {
System.out.print("<<"+e+">>");
}
如果您将catch (RuntimeException e)
替换为catch (QueueTe)
:
try {
// some stuff here
throw new QueueT();
} catch (QueueTe e) {
System.out.print("<<"+e+">>");
}
在这里,您可以非常准确地说出要捕获的错误类型。否则,您可能有另一部分代码抛出运行时异常,并且处理几乎完整队列的代码可能会尝试应用于与队列完全无关的异常。如果您只捕获QueueT
例外,则可以更好,更准确地应用代码。
答案 2 :(得分:0)
如果你改变一下catch子句,那么第一次调用的兴趣很容易理解:
try {
// some stuff here
throw new QueueT();
} catch (QueueT e) {
System.out.print("<<"+e+">>");
}
所以你只会捕获QueueT的实例,而不是像null指针那样潜在的其他运行时,这样的异常你最好传播到入口点,以便检测一些编码或设计问题。 事实上,在您首先编写的代码中,您将无法将预期的完整队列案例与实际运行时错误区分开来。您将丢失错误信息,程序将表现为队列已满,而不是
一个好的做法是永远不会捕获异常超类型,既不运行也不抛出(最差的)。
另一个是使用异常后缀命名异常:例如QueueAboutFullException。
如果您捕获异常的位置与您抛出异常的位置大致相同,则另一个不会使用异常编程。选择一个简单的if,因为它的成本远低于中断