Groovy Tip 14 Assert
Assert在Java平台编程特别是Groovy语言中,应该被广泛使用,特别是在编写公用代码或者API中。
假设我们有如下的一个公用方法:
defstatictest(String str1,String str2)
{
println"str1 size: ${str1.length()},str2 size: ${str2.length()}"
}
下面我们来调用这个方法:
test(null,'123')
结果就报如下的错误:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke method length() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:77)
……
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeStaticMethodN(ScriptBytecodeAdapter.java:212)
at base.Testor2.main(Testor2.groovy:17)
这个错误提示比较长,我省略了中间的一大部分。从这个错误提示可以看出这是一个空指针错误,并且是调用“length()”方法的对象为空。这个错误提示已经很详细了,也相当的明白。但是我们的“test(String str1,String str2)”方法中,有两个对象调用了“length()”方法,即“str1”和“str2”,对于这样的一个提示,我们仍然搞不清楚是“str1”为空,还是“str2”为空。
所以,我们需要对“str1”和“str2”两个输入参数进行校验,然后报告错误。我们可以这样写:
defstatictest(String str1,String str2)
{
if(str1==null)
{
println'The first argument can not be null'
}
elseif(str2==null)
{
println'The second argument can not be null'
}
else
{
println"str1 size: ${str1.length()},str2 size: ${str2.length()}"
}
}
下面来进行测试:
test(null,'123')
结果为:
The first argument can not be null
这个测试的结果虽然直观,但只有一句提示,当运行在一个项目中,这句提示容易被淹没在log提示中,我们无法在庞大的log语句中找到这句话。
通过上面的分析,我们知道上面的解决方法是也是不太好的。
当然,我们还可以抛出自定义的Exception,如下:
defstatictest(String str1,String str2)
{
if(str1==null)
{
throwsnew MyNullException('The first argument can not be null');
}
elseif(str2==null)
{
throwsnew MyNullException('The second argument can not be null');
}
else
{
println"str1 size: ${str1.length()},str2 size: ${str2.length()}"
}
}
这样也相当的清楚,但是它的麻烦是要自定义Exception,而且编码也相当的麻烦,公用代码的使用者需要catch这个Exception。
同样是一个比较麻烦的解决方案。
而使用Assert则没有上述的各种烦恼,请看下面的例子:
defstatictest(String str1,String str2)
{
assert str1!=null,'The first argument can not be null'
assert str2!=null,'The second argument can not be null'
println"str1 size: ${str1.length()},str2 size: ${str2.length()}"
}
测试代码如下:
test(null,'123')
测试结果为:
Exception in thread "main" java.lang.AssertionError: The first argument can not be null. Expression: (str1 != null). Values: str1 = null
at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:396)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:676))
……
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeStaticMethodN(ScriptBytecodeAdapter.java:212)
at base.Testor2.main(Testor2.groovy:19)
可以看到这个出错提示,相当的完整,我们的提示语句也在里面,可以具体知道是哪个对象为空。而且又不需要自定义Exception,是一个相当不错的解决方案。
小结:通过上面的比较,我们可以看到在公用代码中使用Assert的优越性,我们应该在公用代码中使用Assert。当然,本文没有详细介绍Assert的使用方法,具体的使用方法可以查找文档来学习。