45

给定:ThrowableException的超类。

当我阅读有关编写自己的“例外”的文本时,我看到了Throwablecatch块中使用的示例,而其他文本显示new Exception()catch块中使用。我还没有看到关于何时应该使用每个的解释。

我的问题是,什么时候应该Throwable使用,什么时候应该new Exception()使用?

catchorelse块内使用:

throw throwable;

或者

throw new Exception();
4

12 回答 12

42

总是抛出一个Exception(从不Throwable)。你通常也抓不到Throwable,但你可以。Throwable 是 and 的超类ExceptionError所以Throwable如果你不仅想捕捉Exceptions还想捕捉 s,你就会捕捉到Error,这就是拥有它的意义所在。问题是,Errors 通常是普通应用程序不会也不应该捕获的东西,所以Exception除非你有特定的理由使用,否则就使用 s Throwable

于 2009-01-31T04:20:50.883 回答
15

(来自评论)提出这个问题的问题是,如果没有构建集合,我需要将“异常”传递给同事正在构建的一段代码。

在这种情况下,您可能想要抛出一个检查异常。您可以抛出一个Exception,它的适当现有子类(除了未选中RuntimeException的子类及其子类),或(例如“ ”)的自定义子类。请参阅Java 异常教程以了解 Java 异常。ExceptionCollectionBuildException

于 2009-01-31T05:05:47.640 回答
9

您不应该真正捕获异常并抛出一个像“新异常”一样通用的新异常。

相反,如果您希望冒泡异常,只需执行以下操作:

try {
    // Do some stuff here
}
catch (DivideByZeroException e) {
    System.out.println("Can't divide by Zero!"); 
} 
catch (IndexOutOfRangeException e) { 
    // catch the exception 
    System.out.println("No matching element found.");
}
catch (Throwable e) {
    throw e; // rethrow the exception/error that occurred
}

我认为,捕获异常并抛出一个新异常而不是引发到代码块的异常并不是一个好习惯,除非您引发一个有用的自定义异常,该异常提供了足够的上下文来逃避原始异常的原因.

于 2009-01-31T04:24:22.497 回答
5

只有两个地方你应该Throwable在代码中看到这个词:

public static void main(String args[])
{
     try
     {
         // Do some stuff
     }
     catch(Throwable t)
     {

     }
 }

public class SomeServlet extends HttpServlet
{
      public void doPost(HttpRequest request, HttpResponse response)
      {
         try
         {
             // Do some stuff
         }
         catch (Throwable t)
         {
              // Log
         }
      }
 }
于 2011-04-12T22:00:21.040 回答
2

Oracle 在其官方教程(“如何抛出异常”)中给出了答案。

首先,它解释了这ThrowablesErrorException类的联合,它们是两个不同的东西

可抛出 = 错误 + 异常

接下来,很明显 anError极其罕见的东西,几乎不可能从中恢复

当 Java 虚拟机发生动态链接失败或其他硬故障时,虚拟机会抛出 Error。

将 1+1 放在一起,它礼貌地得出结论,(除了简单Exception的 s)捕捉其他Throwables是没有意义的,因为你对它们无能为力。

简单的程序通常不会捕获或抛出错误。

于 2019-11-15T16:42:56.403 回答
1

Throwable 是一个接口,而不是一个类。两个类扩展了 Throwable,Exception 和 Error。

规则是:在捕获异常时尽可能具体——这意味着例如捕获 Exception 而不是 Throwable,以及 IOException 而不是 Exception。

不要捕获错误 - 错误是错误。改为修复代码。

如果你必须捕获所有东西,请使用“catch Throwable”,但这是一种不好的形式。

于 2009-01-31T04:20:58.993 回答
1

throw new Exception();是你永远不应该在 catch 块中做的事情,但你可能不得不或想要做 throw new SomeException(throwable);(保留完整的堆栈跟踪)而不是throw throwable;为了符合你的方法的 API,例如当它声明抛出SomeException但你'重新调用可能会抛出IOException您不想添加到方法throws子句中的代码。

可能最常见的情况是完全new RuntimeException(throwable);避免使用throws子句。许多人会告诉你这是一种可怕的滥用,因为你应该使用受检异常。IMO 他们是错误的,检查异常是 Java 语言设计中的一个错误,只会导致丑陋、不可维护的代码。

于 2009-01-31T09:45:53.923 回答
0

正如我在 java 刚出现时听到的那样,理论是 Throwable 可能用于除异常之外的其他情况下的控制转移。不过,我从未见过它以这种方式使用(这可能是一件非常好的事情)。

所以只需捕获异常(或者更好的是,更细粒度的异常)。

于 2009-01-31T04:30:11.177 回答
0

Throwable 意味着只能被程序的容器或主循环捕获。大多数情况下,捕捉异常(例如错误)下的内容并不会为程序增加太多功能,毕竟如果抛出 VirtualError 其他错误,您可以做些什么。除了记录并继续之外没有太多。

于 2009-01-31T04:33:29.483 回答
0

所有的异常最终都是一个问题......也说错误是错误并不意味着什么。

错误不是错误——它们是主机虚拟机遇到的问题,例如 OutOfMemoryError。异常是当前操作可以用来通知它失败并可能提供一些诊断的一种手段。

于 2009-02-01T02:47:45.717 回答
0

通常,您不会投掷或接住 Throwable。特别是,JVM 错误(扩展 Error() )不应该被用户代码捕获,除非您正在做奇怪的系统级工作。

将“Throwable”视为语言工件。之所以命名“异常”类,是因为它是程序员希望代码块“异常”退出时使用的类 - 通过不正常退出或返回值。

这包括常规错误情况(我的意思是“常规”,而不是 JVM 错误)以及您使用异常作为控制机制的地方。

于 2009-02-01T07:29:41.343 回答
0

您也不应该将异常用作“返回类型”...

如果您要抛出的条件很常见,那么您将花费大量资源将该条件返回给调用例程。异常的构建成本很高。

我见过一些情况,其中紧密循环将异常作为“负面”抛出,例如 ID 分配,这个例程占用了大约 99% 的 CPU 时间。当改为记录的返回常量时,这个比例下降到 25%。

于 2010-03-04T16:05:33.667 回答