mirror of
https://github.com/sjsdfg/effective-java-3rd-chinese.git
synced 2025-03-03 13:50:57 +08:00
Update 69. 只针对异常的情况下才使用异常.md
This commit is contained in:
parent
08b83634d8
commit
32d7db6f19
@ -22,7 +22,7 @@ for ( Mountain m : range )
|
||||
那么为什么有人会企图使用基于异常的循环,而不是使用行之有效的模式呢?这是他们误以为可以使用 Java 的错误判断机制来提高程序性能,因为 VM 对每次数组访问都要检查越界情况,所以他们认为正常的循环终止测试被编译器隐藏了,但是在 for-each 中仍然可见,这是多余的并且应当避免。这种想法有三个错误:
|
||||
|
||||
- 因为异常设计的初衷适用于不正常的情形,所有几乎没有 JVM 实现试图对他们进行优化,使它们与显式的测试一样快。
|
||||
- 把代码放在 try-catch 块中反而组织了现代 JVM 实现本可能执行的某些特定优化。
|
||||
- 把代码放在 try-catch 块中反而阻止了现代 JVM 实现本可能执行的某些特定优化。
|
||||
- 对数据进行遍历的标准模式并不会导致冗余的检查。有些 JVM 实现会将它们优化掉。
|
||||
|
||||
实际上基于异常的模式比标准模式要慢得多。在我本地的机器上,对于一个有 100 个元素的数组进行遍历,标准模式比基于异常的模式快了 2 倍。
|
||||
@ -61,4 +61,4 @@ try {
|
||||
|
||||
对于“状态测试方法”和“optional 返回值或者可识别的返回值”这两种做法,有些指导原则可以帮助你在两者之间做出选择。如果对象将在缺少外部同步的情况下被并发访问,或者可被外界改变状态,就必须使用“optional 返回值或者可识别的返回值”,因为在调用“状态测试”方法和调用对应的“状态相关”方法的时间间隔之中,对象的状态有可能发生变化。如果单独的“状态测试”方法必须重复“状态相关”方法的工作,从性能的角度考虑,就必须使用可被识别的返回值。如果其他方面都是等同的,那么“状态测试”方法则优于可被识别的返回值。他提供了相对更高的可读性,对于使用不当的情形可能更加易于检测和改正:如果忘了去调用状态测试方法,状态相关的方法就会抛出异常,使得这个 Bug 变得很明显;如果忘了去检查可识别的返回值,这个 Bug 就很难被发现。optional 返回值不会有这方面的问题。
|
||||
|
||||
总而言之,异常是为了在异常情况下被设计和使用的。不要将它们勇于普通的控制流程,也不要编写迫使它们这么做的 API。
|
||||
总而言之,异常是为了在异常情况下被设计和使用的。不要将它们勇于普通的控制流程,也不要编写迫使它们这么做的 API。
|
||||
|
Loading…
Reference in New Issue
Block a user