27

我知道

throw new Exception();

有相当大的开销,因为它创建了一个完整的堆栈跟踪等

throw new Throwable();

提出同样的问题?这种行为是继承的,还是抛出 Throwable 的开销较小(o 否)?

编辑
分析师的角度来看,输入错误密码的用户是程序正常执行顺序的例外。所以如果我有:

public Session newSession() {  
  validate_user_and_password();   
}

从分析师的角度来看,抛出 UserNotValidException 听起来是正确的。
如果您的代码具有非常好的抽象,则返回null0只是听起来不正确。我只是想知道我是否可以在代码中真正实现这一点,或者我是否不得不将其留给理论。

编程观点异常和分析师观点异常之间有很大的区别。

注意:我给出了一个非常简单和愚蠢的例子,这不是我的情况。
注2:我知道返回null是很平常的事情,但是我需要有适当的抽象和OO代码,而且,就我个人而言,我认为这没有什么坏处。

4

8 回答 8

49

Throwable创建时还会创建一个堆栈跟踪。来自java 文档Throwable

throwable 包含其线程在创建时的执行堆栈的快照。

Exception因此,就创建堆栈跟踪的开销而言,和之间应该没有区别Throwable

如果您对“异常事件”使用异常(应该如此),那么您不应该太担心堆栈跟踪的开销。运行代码中很少发生异常事件。所以异常不应该以任何显着的方式影响正常代码的性能。

于 2010-01-25T01:11:41.133 回答
37

不,您需要自己的子类来避免这种影响。

Exception ex = new Exception() {
    @Override public Throwable fillInStackTrace() {
        return this; // and do nothing else
    }
};

这会创建一个不会填充堆栈跟踪的异常实例(创建异常委托fillInStackTrace以实际填充堆栈跟踪),因此创建起来很便宜。

于 2010-01-25T01:12:40.960 回答
3

使用 JIT 编译,实际上Exception在 Java 中抛出 an 的情况并不多见。但是抛出 aThrowable并没有太大的不同,因为你也会在那里得到一个堆栈跟踪。

如果您有兴趣,有一篇非常有趣的论文,名为“即时编译中的高效 Java 异常处理”(链接)。读起来不轻松,但信息量很大。

于 2010-01-25T01:13:01.223 回答
1

你永远不应该抛出或捕获Throwable.异常的范围太大。

如前所述,应仅在需要时使用异常,即:在异常情况下并且应针对产生它们的情况。除此之外,捕获 aThrowable意味着许多异常,例如OutOfMemoryException. 这种量级的错误无法(轻松)恢复,并且不应由开发人员处理。

于 2010-01-25T06:12:36.947 回答
1

Throwable是异常的父类。所以Exception class继承自Throwable.

于 2014-01-22T13:03:37.177 回答
1

Throwable vs. 异常

Java 异常

正如@mangoDrunk 所说:“Throwable 是异常和错误的超类。”

于 2015-05-12T07:31:22.307 回答
1

您可以查看这两个类的源代码,看看Exception除了公开与Throwable. 所有的肉,因此开销,住在Throwable

即使Exception确实引入了一些额外的开销,使用它也将是一个明显的过度优化Throwable。为工作使用正确的工具,不要仅仅因为它更轻而选择错误的工具。

于 2017-02-24T01:38:58.763 回答
0

java.lang.Exceptionextends java.lang.Throwable,所以它的开销是一样的。从Javadoc

Throwable 类是 Java 语言中所有错误和异常的超类。只有作为此类(或其子类之一)实例的对象才会被 Java 虚拟机抛出,或者可以被 Java throw 语句抛出。同样,只有此类或其子类之一可以是 catch 子句中的参数类型。

两个子类的实例,错误和异常,通常用于指示发生了异常情况。通常,这些实例是在异常情况的上下文中新创建的,以便包含相关信息(例如堆栈跟踪数据)。

于 2010-01-25T01:15:49.490 回答