美文网首页
Effective Java(3rd)-Item71 避免不必要

Effective Java(3rd)-Item71 避免不必要

作者: 难以置信的优雅 | 来源:发表于2018-09-18 15:07 被阅读0次

      许多Java程序员不喜欢检查异常,但是如果使用得当,它们可以改进api和程序。与返回代码和未检查异常不同,它们迫使程序员处理问题,提高了可靠性。也就是说,在api中过度使用已检查异常会使它们的使用变得不那么令人愉快。如果一个方法抛出检查过的异常,调用它的代码必须在一个或多个catch块中处理它们,或者声明抛出它们并让它们向外传播。无论哪种方式,它都给API的用户带来了负担。Java 8中的负担增加了,因为抛出已检查异常的方法不能直接在流中使用(项目45-48)。
      如果不能通过正确使用API来防止异常情况,并且使用API的程序员在遇到异常时可以采取一些有用的操作,那么这种负担是合理的。除非满足这两个条件,否则可以使用未检查异常。作为一个试金石,问问自己程序员将如何处理异常。这是最好的办法吗?


    或者这样?
    image.png
    如果程序员不能做得更好,则需要一个未检查的异常。
      如果检查异常是方法抛出的惟一检查异常,那么检查异常给程序员带来的额外负担就会大得多。如果还有其他方法,则该方法必须已经出现在try块中,并且此异常最多需要另一个catch块。如果一个方法抛出一个检查过的异常,那么这个异常就是该方法必须出现在try块中而不能直接在流中使用的唯一原因。在这种情况下,有必要问问自己是否有办法避免检查异常。
      消除已检查异常的最简单方法是返回所需结果类型的Optional结果(item55)。该方法只返回一个空的Optional异常,而不是抛出一个已检查的异常。这种技术的缺点是,该方法不能返回任何详细说明其无法执行所需计算的附加信息。相反,异常具有描述性类型,并且可以导出方法来提供附加信息(item70)。

      您还可以通过将抛出异常的方法拆分为两个方法,从而将已检查的异常转换为未检查的异常,第一个方法返回一个布尔值,指示是否将抛出异常。这个API重构将调用序列转换为:


    image.png

    转为


    image.png

      这种重构并不总是适当的,但是在适当的地方,它可以使API更易于使用。虽然后一种调用序列并不比前一种调用序列漂亮,但是经过重构的API更加灵活。如果程序员知道调用将成功,或者如果线程失败,则满足于让线程终止,那么重构还允许这个简单的调用序列:
    obj.action(args);
      如果您怀疑普通的调用序列将成为规范,那么API重构可能是合适的。得到的API本质上是第69项中的状态测试方法API,同样的注意事项也适用:如果要并发地访问对象而不需要外部同步,或者对象受外部诱导的状态转换影响,那么这种重构是不合适的,因为对象的状态可能在调用actionallow和action之间发生变化。如果一个单独的actionallowed方法将复制action方法的工作,那么基于性能考虑,重构可能会被排除。
      总之,如果谨慎使用,检查异常可以提高程序的可靠性;当过度使用时,它们会使api难以使用。如果调用者无法从失败中恢复,则抛出未检查的异常。如果恢复是可能的,并且您希望强制调用者处理异常条件,那么首先考虑返回一个Optional。只有当在失败的情况下,这将提供不充分的信息时,您才应该抛出一个已检查的异常。
    本文写于2019.7.22,历时1天

    相关文章

      网友评论

          本文标题:Effective Java(3rd)-Item71 避免不必要

          本文链接:https://www.haomeiwen.com/subject/awtpnftx.html