我问,是否在程序开始时创建一个特定类型的异常实例,而不创建一个新的异常实例,抛出始终相同的异常对象.
我只想举一个例子.通用代码:
if (!checkSomething(myObject)) throw new CustomException("your object is invalid");
替代方案:
static CustomException MYEXP = new CustomException("your object is invalid"); //somewhere else if (!checkSomething(myObject)) throw MYEXP;
当然,我在这里做一些假设:
> MyCustomException没有参数
>客户端代码,无论什么时候是好的做法,都是非常基于异常处理和重构不是一个选择.
所以问题是:
这是一个很好的做法吗?
>这会损害一些JVM机制吗?
>如果是1,是否有可能获得性能? (我想没有,但不确定)
>如果1和3是肯定的,为什么不赞助作为实践?
>如果1是否定的,为什么Martin Odersky在他对Scala的介绍中说,这是Scala在某些情况下的工作原理? (在28.30分钟,他告诉说休息时间已经被抛出异常,观众说这是耗时的,他回答说这个例外并不是每次都创建的)Fosdem 2009
我希望这不是一个闲置/愚蠢的问题,我很好奇.我认为异常处理中的实际成本是处理而不是创建.
编辑
增加了对FOSDEM演示的精确讨论的参考
免责声明:我的代码都没有像提出的代码一样工作,我无意管理这样的异常,我只是在做一个“假设”的问题,这个好奇心是从该视频生成的.我以为:如果在Scala中完成,为什么不在Java中?
解决方法
可能在Scala的实施过程中,有这样的情况是有道理的. (也许他们正在做一些递归的事情,想要提前生成一个异常对象,以防它们内存不足,它们仍然可以产生异常.)他们还有很多关于他们在做什么的信息,所以他们有更好的机会得到正确的但是JVM语言实现者所做的优化是一个非常特殊的例子.
所以你不会打破任何事情,除非你认为提供有误导性的信息是破损的.对我来说似乎是一个很大的风险.
尝试Thomas Eding关于如何创建没有堆栈跟踪的异常的建议似乎有效:
groovy:000> class MyException extends Exception { groovy:001> public Throwable fillInStackTrace() {}} ===> true groovy:000> e = new MyException() ===> MyException groovy:000> Arrays.asList(e.stackTrace) ===> []
另请查看JLS:
The NullPointerException (which is a kind of RuntimeException) that is
thrown by method blowUp is not caught by the try statement in main,
because a NullPointerException is not assignable to a variable of type
BlewIt. This causes the finally clause to execute,after which the
thread executing main,which is the only thread of the test program,
terminates because of an uncaught exception,which typically results
in printing the exception name and a simple backtrace. However,a
backtrace is not required by this specification.The problem with mandating a backtrace is that an exception can be created at one point in the program and thrown at a later one. It is prohibitively expensive to store a stack trace in an exception unless it is actually thrown (in which case the trace may be generated while unwinding the stack). Hence we do not mandate a back trace in every exception.