您想这样做的原因是什么:
void foo() throws Exception
{
// Do something potentially exceptional
}
与其抛出一个现有的或自定义的异常?
您想这样做的原因是什么:
void foo() throws Exception
{
// Do something potentially exceptional
}
与其抛出一个现有的或自定义的异常?
我能够想到两种可能的情况 - 第一种类似的情况是在实现 finalize()
时,你必须抛出 Throwable
:
@Override
protected void finalize() throws Throwable {
super.finalize();
}
需要注意的是,有些人认为finalize方法本身应该被弃用。
可能出现的第二种情况是使用(编写不良的)库时,其方法可能会抛出异常。在这种情况下,如果您不想在该特定方法中处理它,则唯一的选择是将其传递到堆栈上。
个人而言,如果我遇到这种情况,我很可能会立即将其包装在RuntimeException中:
public void doSomething() {
try {
int x = libraryThing.badMethod(); //Library method that throws "Exception"
}
catch(Exception ex) {
throw new RuntimeException("Couldn't do something", ex);
}
}
RuntimeException
的构造函数中的第二个参数在这种情况下非常重要,因为如果它被抛出,它将保留原始异常的堆栈跟踪信息如("Caused by: x")。当然,如果您可以找到一个更具体的RuntimeException
子类,可以保证在该上下文中相关(例如IllegalArgumentException
),那么使用它会更好。RuntimeException
不算太糟糕 - 它仍然很不具体,但至少不会强制调用者明确地捕获所有异常。我不会这么做。它提供的信息最少,无法清楚地说明发生了什么。
我认为目前的最佳实践是优先使用未检查的异常(这是C#的方式)。foo()方法将捕获已检查的异常并将其包装在RuntimeException中。
我要么拼写出异常,要么将它们包装在更具业务特定性的自定义异常中,或者将RuntimeException包装起来。
它允许该方法抛出任意异常。
这可能在框架上下文中发现,其中任意代码以已知签名的方法运行。无论在那种情况下它是否“好”...嗯。我更愿意看到一个特定于框架或运行时的异常。
除此之外,在我看来,它通常是一种反模式。
我经常在我的测试方法中这样做。
@Test
public void testSOmething() throws Exception {
这是我用于单元测试的标准签名,不特别测试是否会抛出异常(大多数情况下都不会)。
在那些测试之外,我不关心我的测试可能会引发什么异常,因为在这些情况下,抛出异常代表被测试方法的失败。
不过,在生产代码中我从来不这么做。
@Expected
,我指的是不需要抛出异常的情况。 - Eric Wilson如果实际列表非常长且不重要,则可以声明 throws Exception
。例如,通过反射调用方法可能会导致多个异常。
一般来说,这意味着代码设计不良或底层库设计不良。如果你发现自己没有充分的理由就声明“throws Exception”,那么考虑抛出RuntimeException。特别是在库代码中。
通常在测试/快速粗略代码中完成,这是非常合理的。
当throws
列表很长和繁琐时,有时会这样做--半合理
一些开发人员/项目对所有内容都这样做,因为他们对“已检查”异常有不同的哲学,这是可以的(我自己对这个话题有两种想法),如果他们不打算与“世界其他地方”共享重要的代码。
根据业务规则定义自己的异常
public void doSomething() {
try {
int x = 10/0; //Library method that throws "Exception"
}
catch(Exception ex) {
throw new Exception("this doesn;t work.there is exception", ex);
}
}
这将覆盖异常方法;
class Exception
{
Exception()
{
}
Exception(String msg)
{
this.msg=msg;
}
}