一尘不染

Java assert关键字有什么作用,什么时候应使用?

java

有哪些现实的例子可以理解断言的关键作用?


阅读 763

收藏
2020-03-04

共2个答案

一尘不染

断言(通过assert关键字)是在Java 1.4中添加的。它们用于验证代码中不变式的正确性。切勿在生产代码中触发它们,并表示存在错误或滥用代码路径。可以在运行时通过命令-ea上的选项将其激活java,但默认情况下未启用它们。

一个例子:

public Foo acquireFoo(int id) {
  Foo result = null;
  if (id > 50) {
    result = fooService.read(id);
  } else {
    result = new Foo(id);
  }
  assert result != null;

  return result;
}
2020-03-04
一尘不染

让我们假设你应该编写一个程序来控制核电站。很明显,即使是最轻微的错误也可能导致灾难性的结果,因此你的代码必须没有错误(假设出于参数考虑,JVM是没有错误的)。

Java不是可验证的语言,这意味着:你无法计算出操作的结果是否完美。这样做的主要原因是指针:它们可以指向任何地方或任何地方,因此无法计算出具有确切值的指针,至少不在合理的代码范围内。鉴于此问题,没有办法证明你的代码总体上是正确的。但是你可以做的是证明你至少在发现每个错误时都会发现它。

这个想法是基于按合同设计(DbC)范式的:你首先(以数学精度)定义方法应该执行的操作,然后通过在实际执行过程中对其进行测试来进行验证。例:

// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
  return a + b;
}

尽管这显然可以正常工作,但大多数程序员不会在其中发现隐藏的错误(提示:Ariane V因类似的错误而崩溃)。现在,DbC定义你必须始终检查函数的输入和输出以验证其是否正常工作。Java可以通过断言来做到这一点:

// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
    assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
  final int result = a + b;
    assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
  return result;
}

如果此功能现在失败,你将注意到它。你将知道代码中存在问题,知道问题出在哪里,并且知道是什么原因引起的(类似于Exceptions)。更重要的是:你会在发生错误时停止正确执行,以防止任何其他代码使用错误的值运行,并可能损坏其控制的内容。

Java异常是一个类似的概念,但是它们无法验证所有内容。如果要进行更多检查(以执行速度为代价),则需要使用断言。这样做会使你的代码膨胀,但是最终你可以在出乎意料的短开发时间内交付产品(越早修复错误,成本越低)。另外:如果你的代码中有任何错误,你将对其进行检测。没有任何漏洞可以通过,并在以后引起问题。

这仍然不能保证没有错误的代码,但是比通常的程序更接近于此。

2020-03-04