【问题标题】:What is the benefits to use assertion in Java's private methods在 Java 的私有方法中使用断言有什么好处
【发布时间】:2023-01-10 16:00:45
【问题描述】:

我正在阅读 Effective Java Item 49。 我对使用断言来验证私有方法中的参数的示例感到有些困惑。

一些帖子解释了为什么我们可以私下使用断言,因为公共方法负责确保传递正确的参数。因此,对私有方法使用断言没有风险。

但是我们为什么不在私有方法中使用Objects.requireNonNull。 既然可以关闭断言,为什么我们仍然私下使用它,如果我们不启用它,它就不会进行验证?

【问题讨论】:

  • 你可以,而且这不是一个糟糕的主意。但想法是输入来自您信任的代码,因此这只是测试问题,而不是验证问题。
  • 断言通常是关闭的,但最好在测试期间打开它们。这样,如果断言不成立,测试就会失败,这意味着代码中存在错误。

标签: java assertion effective-java


【解决方案1】:

我们需要取消你所说的“验证”的意思。

案例 #1:如果您谈论的是模块、库或应用程序中的内部一致性检查,你想在测试时发生,那么 assert 语句是执行此操作的合适方法。

您可能使用 assert 语句实施的那种内部一致性检查可能代价高昂。例如,您可能会“断言”某些不变量在每次操作后为真。当断言检查打开时,这种额外的检查很可能会改变操作的计算复杂性。您不希望这种验证发生在生产中。

案例 #2:如果您正在谈论验证应用程序的外部输入,使用 assert 不是正确的方法。主要原因是可以关闭 Java 断言检查。确实,他们经常在生产中关闭;原因见上。但是您不希望关闭外部(例如用户)输入的验证,因为这很容易导致其他问题,例如数据库中的错误数据、漏洞等。

这种验证不应该使用assert来完成。

案例 #3:在上述两种情况之间,我们有这样一种情况,您正在对(比方说)传递给代码库中某些内部 API 的参数执行防御性验证。

  • 通常您不希望在运行时关闭这些检查。关闭它们可能会使问题的影响(例如以前未检测到的错误)进一步传播。
  • 但通常您不希望其他内部 assert 检查(即案例 1 中的“测试时间”检查)被打开,因为它们可能很昂贵。

所以这意味着您可能也不应该使用 assert 进行这些测试。


根据上述推理,如果您进行验证的方法是publicprivate或其他东西,它并没有什么区别。使用或不使用assert 是一个正交问题。

最后,值得一提的是,许多 Java 程序员完全避免使用 assert 语句。您在测试时使用 assert 进行的许多验证也可以使用模拟来完成。通过完全不使用assert,您可以避免有人通过在生产中打开断言检查来为您的应用程序造成性能问题的情况!

【讨论】:

    猜你喜欢
    • 2021-01-08
    • 2012-05-23
    • 2018-06-07
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2012-10-11
    • 2019-04-19
    相关资源
    最近更新 更多