【问题标题】:Assert keyword in JavaJava中的断言关键字
【发布时间】:2011-04-17 21:31:30
【问题描述】:

您使用assert 关键字还是抛出一些验证运行时异常?它给您带来了什么好处,或者您为什么认为它不值得使用?

【问题讨论】:

    标签: java validation exception assert


    【解决方案1】:

    如果条件为假,Assert 将引发运行时错误 (AssertionError)。断言为您提供了一种简化的方法来记录、检查和执行代码的正确性标准。好处是定义和操作这些正确性条件的语言级别的钩子。如果您希望启用或禁用它们(有关于这是否是一个好主意的争论),您可以从 JVM 命令行执行此操作。下面的一些评论者指出,除非在调试模式下运行,否则默认情况下禁用断言;我的做法是始终在我的包装脚本中添加“-ea”(启用断言)。即使在对性能敏感的代码中,对我来说,权衡取舍也有利于我从断言中获得的安全性/正确性信心。 Assertions at OracleAPI Description for AssertionError

    请注意可能超出您控制范围的预期或意外失败(异常)与断言失败之间的区别 - 断言失败记录了程序员的假设,并指示不正确的程序,而不是意外的外部条件或预期的异常条件。 如果发生断言失败,则解释为程序员误解或错误地表达了程序,而不是其他错误或失败的来源。

    在实践中,我使用它来记录我在生成(特别是私有/内部)代码时做出的明显或非显而易见的假设以及我想要强制执行的不变量,让我自己和其他人清楚为什么做出这些假设,它们是在哪里制造的,以及它们是否经过验证。比cmet好很多,效果一样。这是迈向Design by Contract 的(小)一步。

    Effective Java item #38 “Check Parameters for Validity”(Google BooksAmazon.com)对参数检查和断言的适当使用之间的区别进行了有用的介绍。

    与 SO 相关:(Enabling assertions in netbeans)、(Assertions vs. Exceptions)、(Near duplicate, asking for examples)、(Badly named, but very similar content)

    【讨论】:

    • 想补充一点,断言在运行时默认是禁用的。有命令行开关(-enableassertions 或 -ea)可用于选择性地启用断言。
    • 我认为您的意思是“在非调试代码中禁用”而不是“在运行时禁用”。
    • 使用Netbeans,如何坚持-ea?
    • @Pete:Google-fu 出现了这个:stackoverflow.com/questions/1880587/…
    • 题外话:“Oracle 的断言”让我很生气。还没习惯。
    【解决方案2】:

    andsoj 是正确的。只是为了让您知道,断言的好处是您可以简单地将其关闭(如果您不在 java 命令行中传递 -ea)。当您想确保不会破坏自己的代码时,这个简单的事情使它们非常适合在开发中使用。

    【讨论】:

      【解决方案3】:

      您可以在开发期间使用它来启用某些功能,然后在实时站点上完全禁用它。例如

      ...
      assert debug("xxx");
      ...
      
      static boolean debug(String format, Object... args){ print(...); return true; }
      

      调试语句将在实时站点上添加零开销。

      【讨论】:

      • 您认为这是一种好的做法吗?我认为最好使用一些 Logger.debug() 方法或类似的方法。
      • 我认为普遍接受的最佳实践是避开这类事情,避免潜在的复杂方法调用。特别是如果有一些潜在的副作用(我会将输出到标准输出算作“副作用”)。
      【解决方案4】:

      准确地说你的问题:

      Assert 用于验证语句的条件。

      assert (some condition)
      Example : assert (6 < 7) // condition pass
                assert (6 > 7) // throws AssertionException here
      

      大多数人将 assert 用于 String 的以下用例:(但我个人讨厌使用 assert):

      assert (obj != null || obj.isEmpty() || ... )
      

      我更喜欢使用干净且服务于目的的谷歌番石榴:

      Obj.isNullOrEmpty()
      

      更多信息:http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Strings.html

      【讨论】:

        【解决方案5】:

        它给你带来了什么好处或者你为什么认为它不值得使用?

        按照其他人的建议,将断言用于强制检查是一种危险的做法

        当其他开发人员使用您的库时会发生什么?或者系统管理员或高级用户忘记,或者更糟的是不知道在运行时启用带有 -ea 标志的断言?你失去了所有这些检查,就是这样。

        断言是一种开发工具。标志的默认状态是 off 的事实是一个死的放弃。

        您的应用程序中的任何功能或优势都不应依赖于断言的启用。

        作为背景,断言在 C/C++ 中的使用方式与该特性的来源相同。在 C/C++ 中,开发人员通常可以在编译时传入 #define DEBUG ... 以启用或禁用断言。使用 C/C++ 生产代码通常会关闭此功能。

        从概念上讲,Java 也应该如此。在生产中使用条件和例外。它们本质上是一样的。

        【讨论】:

        • 将此称为“危险做法”,恕我直言,有点过分。这是一种有一些缺点的做法,@kervin 对此进行了非常雄辩的描述,但每种做法都有其优点和缺点。上下文将决定这些利弊是否使这种做法可以接受。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-30
        • 2014-10-26
        相关资源
        最近更新 更多