Java断言未得到充分利用

Dón*_*nal 66 java assertion

我想知道为什么assert关键字在Java中如此少用?我几乎从未见过它们,但我认为它们是个好主意.我当然更喜欢简洁:

assert param != null : "Param cannot be null";
Run Code Online (Sandbox Code Playgroud)

对于冗长的:

if (param == null) {
    throw new IllegalArgumentException("Param cannot be null");
}
Run Code Online (Sandbox Code Playgroud)

我怀疑是因为他们未得到充分利用

  • 他们来得相对较晚(Java 1.4),到那时许多人已经建立了他们的Java编程风格/习惯
  • 它们默认在运行时关闭

Ken*_*tle 61

理论上,断言用于测试不变量,假设必须为真才能使代码正确完成.

显示的示例是测试有效输入,这不是断言的典型用法,因为它通常是用户提供的.

断言通常不在生产代码中使用,因为存在开销,并且假设不变量失败的情况在开发和测试期间被捕获为编码错误.

你对他们"迟到"java的观点也是他们没有被广泛看到的原因.

此外,单元测试框架允许程序化断言的某些需要在被测试代码的外部.

  • @Ken Gentle:"方法参数通常是用户提供的"? (4认同)
  • @SyntaxT3rr0r:在这种情况下,“用户”是通用的 - 当然,包含断言的方法的调用者是类/方法的“用户”,并且传递的值可以是从用户输入、数据查询结果到硬数据的任何内容。 - 编码值。 (2认同)
  • 我认为断言可以用作单元测试的附加组件.您可以在测试方法中嵌入断言,而不是编写单独的测试方法,尤其是作为调试方法的一部分. (2认同)

Ada*_*icz 56

滥用断言来使用它们来测试用户输入.抛出一个IllegalArgumentException无效的输入更正确,因为它允许调用方法捕获异常,显示错误,并做任何需要(再次请求输入,退出,等等).

如果该方法是其中一个类中的私有方法,那么断言就可以了,因为您只是想确保不会意外地将它传递给null参数.您可以使用断言进行测试,当您测试了所有路径并且未触发断言时,您可以将其关闭,这样您就不会浪费资源.它们也像注释一样有用.一个assert在方法的开始是好的文档,他们应该遵循一定的前提条件的维护者,以及assert在与后置的文件到底是什么方法应该做的.它们和评论一样有用; 此外,因为断言,他们实际上测试他们记录的内容.

断言用于测试/调试,而不是错误检查,这就是为什么它们默认是关闭的:阻止人们使用断言来验证用户输入.


Bil*_*ard 18

断言编程

默认情况下,在运行时禁用断言.两个命令行开关允许您有选择地启用或禁用断言.

这意味着如果您无法完全控制运行时环境,则无法保证甚至可以调用断言代码.断言意味着在测试环境中使用,而不是用于生产代码.您无法使用断言替换异常处理,因为如果用户在禁用断言的情况下运行应用程序(默认值),则所有错误处理代码都会消失.


ycl*_*ian 18

在"Effective Java"中,Joshua Bloch建议(在"检查参数的有效性"主题中)(有点像采用的简单规则),对于公共方法,我们将验证参数并在发现无效时抛出必要的异常,并且对于非公开方法(未公开,并且您作为其用户应确保其有效性),我们可以使用断言.

YC


aku*_*uhn 9

@Don,你很沮丧默认情况下关闭断言.我也是,因此写了这个内联它们的小javac插件(即发出字节码if (!expr) throw Ex而不是这个愚蠢的断言字节码.

如果在编译Java代码时在类路径中包含fa.jar,它将发挥其魔力然后告诉

Note: %n assertions inlined.
Run Code Online (Sandbox Code Playgroud)

@see http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions以及github上的https://github.com/akuhn/javac

  • 我真正想要的是一个可以在编译阶段禁用断言的插件.那应该解决二元膨胀问题. (3认同)