因为软件错误让我们作为开发人员看起来很糟糕,并导致其他人看不起我们,所以最好避免编写错误,快速识别和修复错误,或者掩盖我们的错误。有许多博客文章和文章讨论如何避免错误以及如何识别和修复错误,因此在这篇文章中,介绍了一些最有效的策略来彻底解决Java代码库中的问题。1.吞下checkedexceptions当我们不小心将错误引入我们的代码时,异常就是其中之一。在方法上声明throws子句或捕获已检查的异常也很麻烦。这两个问题的解决方案是在可能抛出异常时捕获异常(即使它是运行时异常),并且什么也不做。这使API保持清洁,并且对于已检查的异常几乎无能为力。通过不记录它或对它做任何事情,没有人甚至需要知道它曾经发生过。2.注释掉或删除不满意的单元测试失败的单元测试可能会让人分心,并且很难确定新功能何时会破坏测试。他们还可以揭示我们在更改代码时破坏了某些东西。注释掉这些失败的单元测试将使单元测试报告更加清晰,并且更容易查看其他人的新功能是否破坏了单元测试。3.在基于JUnit的单元测试中使用@Ignore注释掉失败的单元测试似乎令人不快,因此另一个可能更令人愉快的选择是使用@Ignore注释失败的基于JUnit的单元测试方法。4.完全删除个别测试有问题的单元测试都被删除了。5.注释掉攻击性断言我们不一定需要注释掉或删除整个测试。它可以像注释掉或删除单元测试方法中的断言语句一样简单。该方法每次都执行并成功运行,因为没有断言意味着没有方法会失败。当单元测试方法非常长且复杂时,这种方法特别有效,因此不容易发现缺少的断言。6.注释掉带有无用和冗余测试的干扰噪音的单元测试,使用@Ignore注释基于JUnit的单元测试,甚至删除单元测试这些策略对于Java中的干净解决方案来说可能过于明显。为了让这些不那么明显,另一个有效的策略是在同一个单元测试类中写很多不必要和冗余的测试方法,这样看起来像是在做一个全面的测试,但实际上只是其中的一小部分Features(我们知道正在工作的一个子集)正在接受测试。7.编写单元测试来“证明”你的代码是正确的,即使它不是证明我们的代码是正确的。如果我们的添加两个整数的代码在提供2和2时意外返回5的总和,那么我们也可以简单地将单元测试中的预期结果也设置为5。给出一份不错的单元测试报告,没有人是更聪明的。8.避免记录详细信息日志可能会暴露软件问题,应对这种风险的有效方法是根本不记录,只记录常规操作和结果,并在记录的消息中留下详细信息(尤其是上下文)。过度记录平凡的细节也会掩盖任何更有意义的消息,这些消息可能会暴露代码的弱点。9.避免使用描述性的toString()实现描述性的toString()方法可以揭示太多关于任何给定实例的状态,并揭示我们的错误。对象不会被覆盖。toString()会使识别问题以及将问题与任何给定代码或开发人员关联起来变得更加困难。追查问题所需的额外时间让您有更多时间在发现是您的代码有问题之前转移到下一个项目。如果您编写一个Java类来扩展具有描述性toString()的类,那么您可以在扩展类中覆盖该方法而无需执行任何操作(有效地删除会导致toString()出错的输出)。如果您希望它看起来好像从未在继承层次结构中实现过,请确保扩展类的toString()方法返回System.识别哈希码(this)。10.不要让NullPointerExceptions出卖你NullPointerExceptions可能是Java开发人员处理的最常见的异常。这些特别危险,因为它们经常暴露代码中的弱点。一种策略是简单地用try-catch包装每一行代码,然后简单地吞下异常(包括NPE)。另一个不太明显的策略是通过从不返回或传递null来避免NPE。有时使用默认值而不是null是有意义的(例如空字符串或集合),但有时我们必须更有创意地避免null。此时使用“默认”非空值而不是空值很有用。关于如何处理这种任意的非空默认值,有两种思想流派。一种方法是使用数据集中最常见的值作为默认值,因为如果它很常见,当出现更多值时可能不会注意到它,并且您更有可能拥有处理该共同值的代码,而无需事故。另一方面,如果你有一个几乎从不使用的值,这可以作为一个很好的默认值,因为受它影响的代码(尤其是经过良好测试的代码)可能比通常预期的要少。
