Java 中 Exception 与 Throwable 相关的开销
题
我知道
throw new Exception();
有相当大的开销,因为它创建了完整的 stackTrace 等。
做
throw new Throwable();
存在同样的问题吗?这种行为是继承的,还是抛出 Throwable 的开销较小(或没有)?
编辑
来自一个 分析师 从角度来看,用户输入错误的密码是程序正常执行顺序的例外。所以如果我有:
public Session newSession() {
validate_user_and_password();
}
抛出 UserNotValidException 听起来是正确的 分析师 观点看法。
返回 null
或者 0
如果你的代码有很好的抽象,那么听起来就不正确。我只是想知道我是否可以在代码中实际实现这一点,或者我是否必须将其留给理论。
编程观点的异常和分析师观点的异常之间有很大的区别。
笔记:我给出了一个非常简单和愚蠢的例子,这不完全是我的情况。
笔记2:我知道回来 null
这将是很平常的事情,但我需要有正确的抽象和面向对象的代码,而且就我个人而言,我认为这没有什么坏处。
解决方案
Throwable
它的创建时也产生一个堆栈跟踪。从 Java文档为Throwable
:
抛出包含在其创建时间其线程的执行堆栈的快照。
因此,在与关于创建堆栈跟踪开销方面,应该有Exception
和Throwable
之间没有差异。
如果您使用的例外“特殊事件”(你应该是),那么你不应该太在意堆栈跟踪的开销。一个特殊事件中运行代码很少发生。所以例外不应以任何方式显著影响正常代码的性能。
其他提示
不行,你自己的子类,以避免这种效果。
Exception ex = new Exception() {
@Override public Throwable fillInStackTrace() {
return this; // and do nothing else
}
};
此产生异常的一个实例,将不会填充堆栈跟踪(创建例外代表到fillInStackTrace
实际填充堆栈跟踪),因此是廉价的创建。
通过JIT编译,它实际上是不是还是有很多监听的在Java中抛出Exception
的情况。但投掷Throwable
没有太大的不同,因为你将会得到一个堆栈跟踪那里。
如果你有兴趣,有一个叫非常有趣的论文“高效的Java异常处理即时编译”(的链接)。不轻读,但相当丰富。
您应该永远不会被抛出或捕捉Throwable.
例外的范围是远远太大。
如前所述,异常应该只在需要时使用,即:在特殊情况下,应该是特定于催生他们的情况。这且不说,受凉Throwable
意味着例外,如OutOfMemoryException
的主机。这个数量级的误差不能从(容易)回收并不应由显影剂进行处理。
Throwable
是父类的异常。所以Exception class
从Throwable
继承。
java.lang.Exception
延伸java.lang.Throwable
,所以它是相同的开销。从的Javadoc :
在的Throwable类是Java语言中所有错误和异常的超类。只有在此类(或子类之一)的实例对象由Java虚拟机抛出,也可以由Java throw语句抛出。类似地,只有这个类或其子类之一可以是在catch子句的参数类型。
两个子类,错误和异常的情况下,常规地用于指示异常情况时有发生。典型地,这些实例中的异常情况的上下文中新创建的,以便包括相关信息(诸如堆栈跟踪数据)。