Java断言未被使用

我想知道为什么assert关键字在Java中如此不足? 我几乎从来没有见过他们,但我认为他们是一个好主意。 我当然更喜欢简洁的:

 assert param != null : "Param cannot be null"; 

到以下的详细程度:

 if (param == null) { throw new IllegalArgumentException("Param cannot be null"); } 

我的怀疑是,他们没有被充分利用,因为

  • 他们到达比较晚(Java 1.4),到那时候很多人已经确定了他们的Java编程风格/习惯
  • 它们在运行时默认closures,为什么OH为什么?

断言在理论上是为了testing不variables ,假设必须是正确的,以便代码正确地完成。

显示的示例是testing有效的input,这不是断言的典型用法,因为它通常是用户提供的。

在生产代码中通常不使用断言,因为存在开销,并且假定在开发和testing期间,不variables失败的情况已被捕捉为编码错误。

关于他们对Java“迟到”的观点也是他们没有被广泛看到的原因。

而且,unit testing框架允许程序断言的一些需要在被testing代码的外部。

这是滥用断言来使用它们来testing用户input。 抛出IllegalArgumentException对无效input更正确,因为它允许调用方法捕获exception,显示错误,并做任何需要(再次要求input,退出,无论)。

如果这个方法是你的一个类中的一个私有方法,那么这个断言是好的,因为你只是想确保你不会不小心传递一个null参数。 你在断言上进行testing,当你testing了所有path并且没有触发断言时,你可以把它们closures,这样你就不会浪费资源。 作为评论,它们也是有用的。 在方法开始时assert是维护者的良好文档,他们应该遵循某些先决条件,最后用后置条件声明文档应该做什么。 它们可以和评论一样有用; 另外,因为有了断言,他们实际上是testing他们所logging的。

断言是为了testing/debugging,而不是错误检查,这就是为什么它们默认closures:阻止人们使用断言来validation用户input。

从断言编程

默认情况下,断言在运行时被禁用。 两个命令行开关允许您select性地启用或禁用声明。

这意味着如果您不能完全控制运行时环境,则不能保证断言代码甚至会被调用。 断言是为了在testing环境中使用,而不是用于生产代码。 您不能用断言来replaceexception处理,因为如果用户运行断言被禁用( 默认 )的应用程序,那么您的所有error handling代码都将消失。

在“有效的Java”中,Joshua Blochbuild议(在“检查参数的有效性”主题中)(对于公共方法来说,有点像一个简单的规则),对于公共方法,我们将validation参数并发现必要的exception,对于非公开的方法(不公开的方法),你作为他们的用户应该确保其有效性,我们可以使用断言。

YC

@唐,你很沮丧断言是默认closures。 我也是,因此写了这个内嵌的小javac插件(即发出if (!expr) throw Ex字节码而不是这个愚蠢的断言字节码。

如果在编译Java代码的时候将fa.jar包含在类path中,它会发挥它的魔力,然后告诉

 Note: %n assertions inlined. 

@见http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions和github https://github.com/akuhn/javac

我不知道为什么你会写麻烦,然后用条件语句replace它们,为什么不把条件写在首位呢?

断言仅用于testing,并且它们有两个副作用:启用更大的二进制文件和降低的性能(这就是为什么您可以closures它们!)

断言不应该用于validation条件,因为这意味着当运行时,当应用程序被启用/禁用时,应用程序的行为是不同的 – 这是一场噩梦!

断言是非常有限的:你只能testing布尔条件,你需要写一个有用的错误消息的代码,每次。 将它与JUnit的assertEquals()相比较,它允许从input生成一个有用的错误消息,甚至在JUnit runner中的IDE中并排显示两个input。

此外,您目前无法在任何IDE中search断言,但每个IDE都可以search方法调用。

断言是有用的,因为它们:

  • 尽早赶上编程错误
  • 文件代码使用代码

把它们想象成代码自我validation。 如果它们失败了,应该意味着你的程序被破坏了,并且必须停止。 在unit testing的时候总是打开它们!

在“实用程序员”中,他们甚至build议让他们在生产中运行。

保持断言打开

使用断言来防止不可能。

请注意,如果断言失败,断言将抛出AssertionError,因此不会被catchexception捕获。

事实上,他们到达了Java 1.4

我认为主要的问题是,当你在一个你不直接pipe理jvm选项的环境中编写代码时,比如在eclipse或者J2EE服务器中(在这两种情况下,都可以改变jvm选项,但是你需要深入search才能find它的位置可以做到),使用if和except(或者更糟糕的是不使用任何东西)更容易(我的意思是它需要更less的努力)。

正如其他人所说:断言不适合validation用户input。

如果你关心冗长,我build议你看看我写的一个库: https : //bitbucket.org/cowwoc/requirements/ 。 它将允许您使用很less的代码来表示这些检查,甚至会以您的名义生成错误消息:

 requireThat("name", value).isNotNull(); 

如果你坚持使用断言,你也可以这样做:

 assertThat("name", value).isNotNull(); 

输出结果如下所示:

 java.lang.NullPointerException: name may not be null