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