【问题标题】:Correct use Java "assert" keyword正确使用Java“assert”关键字
【发布时间】:2013-09-20 01:19:51
【问题描述】:

我一直不明白assert 是做什么用的,尽管我已经阅读了大量示例,但它们并没有真正让我知道我应该将它用于什么或为什么要使用它。

所以我不会问一个例子,而是提供一个例子,让我知道这是否是 assert 的正确用法。

// The idea is that the `mode` variable should be 0 or 1, and no other number.
switch(mode) {
     case 0: 
          // do stuff
          break;
     case 1:
          // do other stuff
          break;

     default:
          // assert code?
}

如果这是正确的,请告诉我在这种情况下如何使用它。如果这不是它应该使用的方式,请提供一个示例。

【问题讨论】:

  • What does assert do? 的可能重复项
  • 您断言您认为必须为真的布尔表达式。您在编写代码时会做出假设,并且您已经知道它们是什么。

标签: java assert


【解决方案1】:

在这种情况下不是。

如果您要断言一个值,那么您就是在声明,在使用该值进行一些关键评估之前,它就是您断言它的样子。您可以断言该值不为空,或者小于 2,或者在您到达关键代码块之前

assert (mode >= 0 && mode < 2);  // Ensures that `mode` is between 0 and 1.
// Switch statement to follow

我不鼓励在这里使用它。您的代码不会很好读,除非您使用 -ea 标志启用断言,否则您的断言将不起作用。

相反,您可以做的是抛出某种异常 - 如果它不是 0 或 1,那么 mode 是一个无法处理的非法值,从而导致异常/未定义的行为。抛出某种异常。

switch(mode) {
    case 0: 
        // do stuff
        break;
    case 1:
        // do other stuff
        break;
    default:
      throw new IllegalArgumentException("Mode is illegal");
}

【讨论】:

  • +1 偏移;抛出异常,IMO,比assert 更可取。如果断言被关闭怎么办?例如,默认?
  • @DaveNewton 虽然我同意你关于例外的观点,但重要的是要注意断言具有自我记录的效果。有时拥有assert 是适当且有益的,即使您确定它的条件永远不会是错误的。
  • @arshajii:我个人不觉得现在是这样的时候。如果有任何疑问,抛出一个明确的异常并强制调用者处理这个问题是更可取的;如果断言被禁用,那么这些条件可能会被取消选中。
  • @arshajii 如果您确定条件永远不会为假,那么抛出异常就像自我记录一样,并且不依赖于显式启用的断言。断言是一种开发时工具;在运行时可能出错的事情应该用异常或正常的流控制来处理。
  • @arshajii 我还是不明白你的意思。断言在关闭时是无用的。它们是一种开发工具。它们并没有比这更广泛。
【解决方案2】:
assert object != null;
object.doSomething();

assert 用于验证某些前置条件、不变量或后置条件的正确性。在示例中,我们要确保在调用某个方法时object 不是null

要记住的一点是,assert 永远不应该在生产代码中执行。我们只在测试时使用它。有一个 Java 选项可以打开或关闭它。

至于您的具体示例,您可以使用:

assert mode == 0;
assert mode == 1;

在 switch 块的最开始,确保只有 01 被传入。

附: when to use assertion vs exception 的讨论可能有助于您的理解。这个想法是

异常处理应用程序的健壮性,而断言 解决您的应用程序的正确性。

【讨论】:

  • @IgorGanapolsky 他们不应该。它们是一种开发工具。条件和异常对生产代码做同样的事情。断言的一个核心特性是它们忽略性能,您可以根据需要使用任意数量的断言,因为它们不会影响编译出来的生产性能。
【解决方案3】:

断言基本上用于检查不应该发生的事情。 来自http://www.javapractices.com/topic/TopicAction.do?Id=102的一些断言用例

前置条件(仅在私有方法中)- 方法要求其调用者满足的要求。 后置条件 - 验证方法对其调用者的承诺 类不变量 - 验证对象状态 unreachable-at-runtime code - 程序中您希望无法访问但在编译时无法验证的部分(通常是 else 子句和 switch 语句中的默认情况)

所以你的代码中断言的使用是不正确的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 1970-01-01
    • 2011-06-27
    相关资源
    最近更新 更多