单例异常是否有效?

Inv*_*con 8 java singleton static exception

我的一位同事在工作中介绍了静态工厂方法(在Effective Java之外),然后给出了一个用于获取静态/单例异常的示例.

这给我带来了一面红旗.有例外是否有状态?它们不是由JVM填充堆栈跟踪信息吗?你真正得到了什么节省,因为异常应该仅在特殊情况下发生?

我对异常的了解相当有限,所以我带着这个来找你:单例异常是否有效,有没有理由使用它们?

Jam*_*hek 17

单例异常应该是性能优化.我们的想法是,在创建异常(通常是异常中最昂贵的部分)时,可以消除填充堆栈跟踪的成本.

如果异常足够独特且具有描述性并且不会使用堆栈跟踪,则单例可能有效.您可以设计应用程序,使具有特定消息的特定异常类型始终表示从特定位置开始的异常.然后堆栈跟踪将无关紧要.

2003年4月22日技术技巧文章描述了你重用异常的情况.在这种情况下,他们试图通过减少创建的对象数来对垃圾收集器进行游戏.如果您跳过了populateStackTrace()通话,则无需担心线程.

通常,如果异常的性能影响导致问题,则表明应用程序逻辑正在使用异常,而应使用错误代码.

在较新的JVM(1.4+,我相信)中,这种"优化"可以在"-server"模式下运行时由JVM自动完成.此热点优化可由该选项控制-XX:+OmitStackTraceInFastThrow.

就个人而言,我建议不要使用单例异常[反]模式.

  • 如果一个JVM从同一位置被多次抛出,由`-XX:[+ - ] OmitStackTraceInFastThrow` JVM选项控制,JVM实际上会开始抛出单例RuntimeExceptions(例如NPE).因此,如果有人向您发送带有NPE且没有回溯的日志,那可能就是为什么:) (4认同)
  • 有趣的答案.我最强烈地同意你的第三段; 异常应该是例外的,如果它们频繁发射以导致性能问题,则必须重新考虑代码. (3认同)