我知道
throw new Exception();
有很大的开销,因为它创建了一个完整的stackTrace,等等 确实
throw new Throwable();
出现同样的问题?这种行为是继承的,还是抛出Throwable有一个较小的(o no)开销?
修改
从分析师的角度来看,插入错误密码的用户是程序正常执行顺序的例外。如果我有:
public Session newSession() {
validate_user_and_password();
}
从分析师的角度来看,抛出UserNotValidException听起来是正确的。
如果您的代码具有相当好的抽象,则返回null
或0
听起来不正确。我只是想知道我是否可以在代码中实现这一点,或者我是否必须将它留给理论。
编程视点异常与分析师观点异常之间存在很大差异。
注意:我给出了一个非常简单而愚蠢的例子,这不是我的情况
注2:我知道返回null
将是普通的事情,但我需要有适当的抽象和OO代码,而且,就个人而言,我认为没有任何损害。
答案 0 :(得分:49)
Throwable
在创建堆栈跟踪时也会创建堆栈跟踪。来自java docs for Throwable
:
throwable包含其创建时线程执行堆栈的快照。
因此,就创建堆栈跟踪的开销而言,Exception
和Throwable
之间应该没有区别。
如果您使用“异常事件”的异常(就像您应该这样),那么您不应该过多关注堆栈跟踪的开销。在运行代码中很少发生异常事件。因此,异常不应以任何重要方式影响正常代码的性能。
答案 1 :(得分:37)
不,你需要自己的子类来避免这种影响。
Exception ex = new Exception() {
@Override public Throwable fillInStackTrace() {
return this; // and do nothing else
}
};
这会创建一个异常实例,它不会填充堆栈跟踪(创建异常委托给fillInStackTrace
以实际填充堆栈跟踪),因此创建起来很便宜。
答案 2 :(得分:3)
使用JIT编译,实际上并不是在Java中抛出Exception
有很多被无法听到的情况。但抛出一个Throwable
并没有太大的不同,因为你也会得到一个堆栈跟踪。
如果您感兴趣,有一篇非常有趣的论文称为“即时编译中的高效Java异常处理”(link)。不是轻松阅读,但信息量很大。
答案 3 :(得分:1)
你永远不应该抛弃或捕捉Throwable.
例外的范围太大了。
如前所述,只有在需要时才应使用例外情况,即:在特殊情况下,应特定于产生它们的情况。除此之外,捕获Throwable
意味着一系列例外,例如OutOfMemoryException
。这种程度的错误无法从(轻松)恢复,不应由开发人员处理。
答案 4 :(得分:1)
Throwable
是Exception的父类。因此Exception class
继承自Throwable
。
答案 5 :(得分:1)
您可以查看这两个类的源代码,看看Exception
除了公开与Throwable
相同的构造函数之外没有做任何事情。所有的肉,因此头顶上都存在Throwable
。
即使Exception
确实引入了一些额外的开销,使用Throwable
也会明显过度优化。使用合适的工具完成工作,不要仅仅因为工具较轻而选择错误的工具。
答案 6 :(得分:0)
java.lang.Exception
扩展java.lang.Throwable
,因此开销相同。来自Javadoc:
Throwable类是Java语言中所有错误和异常的超类。只有作为此类(或其子类之一)的实例的对象才被Java虚拟机抛出,或者可以被Java throw语句抛出。类似地,只有这个类或其子类之一可以是catch子句中的参数类型。
两个子类的实例,Error和Exception,通常用于表示发生了异常情况。通常,这些实例是在特殊情况的上下文中新创建的,以便包括相关信息(例如堆栈跟踪数据)。
答案 7 :(得分:0)