Google Guava vs Apache Commons for Argument Validation
2014-04-10 00:07 Rollen Holt 阅读(5733) 评论(0) 编辑 收藏 举报It is an established good practice to validate method arguments at the beginning of the method body. For example you could check that the passed value is not negative before doing some calculation:
1
2
3
4
5
6
|
public int doSomeCalculation( int value) { if (value < 0 ) { throw new IllegalArgumentException( "negative value" ); } ... } |
It can be written slightly shorter using the good old Apache Commons:
Validate.isTrue(value >= 0 , "negative value" ); |
More recently the same behavior can be achieved with Google Guava after statically importing the Preconditions
class:
checkArgument(value >= 0 , "negative value" ); |
At surface it looks quite similar but usually the devil is in the details so I decided to take a closer look at both approaches. In this post I’m going to describe the differences between the two libraries regarding argument validation.
Static imports
The first immediately obvious difference is that Guava requires static import to look nice.Validate.isTrue()
looks better than Preconditions.checkArgument()
. Personally, I don’t mind static imports in my code. For some people it might be a small disadvantage though. Especially for those who don’t know how to work with them in the IDE yet. Also, if you work on some ancient project that still uses Java earlier than 5.0 you won’t be able to use Guava at all.
Types of exceptions
All methods from Validate
class in Apache Commons throw IllegalArgumentException
when validation fails. Sometimes it make sense to throw a different exception type. Guava make it possible. For example:
checkArgument
throwsIllegalArgumentException
checkState
throwsIllegalStateException
checkNotNull
throwsNullPointerException
checkElementIndex
andcheckPositionIndex
throwIndexOutOfBoundsException
, etc.
It’s obvious from the method name what exception gets thrown. I like this clear distinction in Guava.
Message parameters
It’s a good idea to give as much information about the failure as possible. For example if you validate that a number is positive you should add the actual number in the exception message if it’s not. In the example below it is done using the string concatenation directly:
Validate.isTrue(i > 0 , "Should be positive but was: " + i); |
In Commons Validate.isTrue()
method you can pass additional parameter instead. It offers a performance benefit because the string concatenation is actually done only when the validation fails.
Validate.isTrue(i > 0 , "Should be positive but was: " , i); |
You can do a similar thing in Guava:
checkArgument(i > 0 , "Should be positive but was: %s" , i); |
Additionally, Guava uses varargs for message parameters and you could also write:
checkArgument(i > MIN, "Expected more than %s, got %s" , MIN, i); |
In this case it’s also more readable than using string concatenation:
checkArgument(i > MIN, "Expected more than " + MIN + ", got " + i); |
Validating collections and arrays
Apache Commons has some additional validations for collection and arrays that you won’t find in Guava:
allElementsOfType(Collection collection, Class clazz)
Validate.notEmpty(Collection collection)
Validate.notEmpty(Map map)
Validate.notEmpty(Object[] array)
Validate.noNullElements(Collection collection)
Validate.noNullElements(Object[] array)
This first one might be handy in legacy project not using generics. Others are generally useful.
On the other hand you can combine Guava Preconditions
with any utility methods. In the example below I use the isNotEmpty
method from Commons CollectionUtils
in conjunction with Guava Preconditions
to ensure that the list is not null and not empty:
checkArgument(isNotEmpty(list)); |
Assignment after validation
It’s common to assign a method argument to a field after validation. For example withValidate
from Apache Commons you could write:
1
2
3
4
|
public Class(Object parameter) { Validate.notNull(parameter); this .field = parameter; } |
The checkNotNull
from Guava Preconditions
returns the validated reference. This allows validation and assignment in one line:
1
2
3
|
public Class(Object parameter) { this .field = checkNotNull(parameter); } |
Summary
In summary, here are the main advantages of both classes:
Apache Commons Validate
- Works in old versions of Java
- Readable without static imports
- Collection and array validations
Google Guava Preconditions
- Additional exception types
- Better handling of message arguments
- Easy assignment after not null check
Verdict
I prefer Guava Preconditions
over Commons Validate
for argument validation.
==============================================================================
本博客已经废弃,不在维护。新博客地址:http://wenchao.ren
我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他
们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其
实我是一个程序员
==============================================================================
![](http://service.t.sina.com.cn/widget/qmd/1882500857/8c17d4b5/1.png)