您是否有理由这样做:
void foo() throws Exception
{
// Do something potentially exceptional
}
而不是抛出现有的或自定义的异常?
答案 0 :(得分:5)
我可以想到两个案例 - 我能想到的第一个类似案例是在实施finalize()
时,你必须抛出Throwable
:
@Override
protected void finalize() throws Throwable {
super.finalize();
}
......但是请记住,有人认为应该不鼓励使用finalize。
潜在的第二种情况是使用(编写得很糟)的库,其方法可能抛出Exception
,在这种情况下,如果您不想在该特定方法中处理它,您唯一的选择是把它扔到堆栈。
就个人而言,如果那是我,我很可能会在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
的构造函数的第二个参数在这种情况下很重要,因为如果抛出它会将堆栈跟踪上的原始异常保留为(“由...引起”)。当然,如果你能找到一个更具体的RuntimeException子类,你可以保证它在那个上下文中是相关的(例如IllegalArgumentException
),那么使用它会更好。
然而,就普通代码而言,没有 - 我认为它几乎总是一种反模式(通常只是因为懒惰造成的!)
作为一个侧面点,抛出一个RuntimeException
并不是那么糟糕 - 它仍然非常不明确,但至少不会强迫调用者明确地捕获所有内容。
答案 1 :(得分:3)
我不会这样做。它提供了有关所发生事件的最少信息。
我认为目前的最佳做法是选择未经检查的异常(这是C#方式)。 foo()方法将捕获已检查的异常并将它们包装在RuntimeException中。
我要么拼出异常,将它们包装在更具体业务的自定义异常中,要么包装RuntimeException。
答案 2 :(得分:3)
它允许该方法抛出任意异常。
这可以在框架上下文中找到,其中任意代码在具有已知签名的方法中运行。在这种情况下它是否“好”......呃。我宁愿看到特定于框架或运行时的异常。
除此之外,它通常是反模式,IMO。
答案 3 :(得分:3)
我经常在我的测试方法中这样做。
@Test
public void testSOmething() throws Exception {
这是我的单元测试的标准签名,它没有专门测试是否抛出异常(这是大多数测试。)
在这些测试之外,我不关心我的测试可能会抛出什么异常,因为在这些情况下抛出异常表示测试方法失败。
我从不在生产代码中这样做。
答案 4 :(得分:2)
如果实际列表很长且没有意义,您可以声明throws Exception
。例如当通过反射调用方法时,这可能会导致相当多的异常。
答案 5 :(得分:2)
您可能正在实现Java自己的Callable界面!这总结了一下。如果你提供一些其他人的代码可以运行的上层结构,但你不想限制它们被强制捕获内部的任何和所有已检查的异常。有人可以断言,这对你自己的图书馆本身来说并不坏,但是首先是设置了一个糟糕的Checked Exceptions设计的危险(但那时我们将进行圣战,而不是SO问题。)< / p>
答案 6 :(得分:1)
一般来说,这意味着代码设计不好或底层库设计不好。如果您发现自己没有充分理由声明“抛出异常” - 请考虑抛出RuntimeException。特别是在图书馆代码中。
答案 7 :(得分:0)
通常我发现“throws Exception”对于在其他人实现的接口中声明的方法是可接受的,并且可以有非常不同的实现(你不希望在他们可能抛出的内容中限制可能的实现)。 / p>
当从方法中抛出很多异常时,我发现它也是可以接受的。
我不认为这是一种反模式,而是一种常用于懒惰的习语。
答案 8 :(得分:0)
根据业务规则定义您自己的异常
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;
}
}
答案 9 :(得分:0)
它通常在测试/快速和肮脏的代码中完成,这是非常合理的。
当throws
列表冗长乏味 - 半合理
有些开发人员/项目会为所有事情做这件事,因为他们对“已检查”异常有不同的理念,如果他们不打算进行重要的代码共享,那么就可以了(我自己对这个主题有两个想法)与“世界其他地方”。