2008-11-18 90 views
64

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

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

到的详细程度:

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

我怀疑是他们未充分利用的,因为

  • 他们到达比较晚(Java 1.4中) ,那时很多人已经建立了他们的Java编程风格/习惯
  • 它们在运行时默认关闭,为什么OH为什么?
+0

它是Java 1.4中介绍了断言。 – 2008-11-18 19:12:08

+12

注意:你可以写assert param!= null:“Message”;即。放下括号。与返回一样多(someValue);这是一种语言功能,不是函数调用。 – PhiLho 2008-12-15 09:16:15

+0

@丹恩谢谢,我已经更新了问题 – 2009-11-09 14:40:13

回答

62

断言是,在理论上,测试invariants,假设必须为了是真实的代码正确完成。

示出了用于有效的输入,这对于一个断言一个典型的使用正在测试,因为它是例如,通常,用户提供。

断言并不一般在生产代码中使用,因为有一个开销,假设在不变的情况下失败被抓的开发和测试过程中编码错误。

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

此外,单元测试框架允许一些需要编程断言为外部代码被测试。

0

事实上,他们在Java中到达1.4

我认为主要的问题是,当你的代码的环境下你不喜欢自己的Eclipse或J2EE服务器直接管理JVM选项(在这两种情况下,它可以改变jvm选项,但是你需要深入搜索才能找到它可以完成的地方),使用if和exception(或者更糟糕的是不使用任何东西)会更容易(我的意思是它需要更少的努力)。

1

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

而且,你不能搜索断言在迄今为止我见过的任何IDE但每一个IDE可以搜索方法调用。

19

Programming with Assertions

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

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

56

这是滥用断言来使用它们来测试用户输入。在无效输入上抛出IllegalArgumentException更正确,因为它允许调用方法捕获异常,显示错误并执行所需的任何操作(再次请求输入,退出,无论如何)。

如果该方法是里面的类中的一个私有方法,断言是好的,因为你只是想确保你不小心传递一个空参数。您可以使用断言进行测试,并且当您测试了所有路径并且未触发断言时,可以关闭它们,以免浪费资源。作为评论,它们也很有用。一个方法开始时的assert对于维护者来说应该是遵循某些先决条件的良好文档,并且末尾有一个assert,后续条款记录了该方法应该做什么。它们可以与评论一样有用;另外,因为有了断言,他们实际上是在测试他们记录的内容。

断言是用于测试/调试,没有错误检查,这就是为什么他们是默认关闭的:从使用断言验证用户输入的劝阻人。

18

在“有效的Java”,约书亚布洛赫建议(在“检查有效参数”主题)是(有点像一个简单的规则采用),用于公共方法,我们将验证的参数,如果抛出必要的异常发现无效,对于非公开的方法(它们没有公开,你作为它们的用户应该确保它们的有效性),我们可以使用断言。

YC

2

我不知道为什么你会懒得写断言,然后用标准的替换他们,如果再条件语句,为什么不写条件如同第一个地方?

断言仅用于测试,他们有两个副作用:(!这就是为什么你可以将其关闭)启用时较大的二进制文件,并导致性能下降

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

1

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

  • 捕捉编程错误早期使用代码

认为他们

  • 文件代码代码自我验证。如果它们失败了,它应该意味着你的程序被破坏并且必须停止。在单元测试时始终打开它们!

    The Pragmatic Programmer他们甚至建议让他们在生产中运行。

    离开断言已打开

    用断言防止不可能。

    请注意,断言抛出AssertionError,如果他们失败,所以不抓捕获异常。

  • 0

    正如其他人所说:断言不适合验证用户输入。

    如果您关心的是详细程度,我建议您查看我写的图书馆:https://bitbucket.org/cowwoc/requirements/。这将允许您使用很少的代码来表示这些检查,它甚至会产生对你代表的错误消息:

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

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

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

    输出将是这样的:

    java.lang.NullPointerException: name may not be null