Google Guava vs Apache Commons for Argument Validation
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 IllegalArgumentExceptionwhen validation fails. Sometimes it make sense to throw a different exception type. Guava make it possible. For example:
checkArgumentthrowsIllegalArgumentExceptioncheckStatethrowsIllegalStateExceptioncheckNotNullthrowsNullPointerExceptioncheckElementIndexandcheckPositionIndexthrowIndexOutOfBoundsException, 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.
Google Guava vs Apache Commons for Argument Validation的更多相关文章
- [Google Guava] 1.2-前置条件
原文链接 译文链接 译者: 沈义扬 前置条件:让方法调用的前置条件判断更简单. Guava在Preconditions类中提供了若干前置条件判断的实用方法,我们强烈建议在Eclipse中静态导入这些方 ...
- 使用 Google Guava 美化你的 Java 代码
文章转载自:http://my.oschina.net/leejun2005/blog/172328 目录:[ - ] 1-使用 GOOGLE COLLECTIONS,GUAVA,STATIC IMP ...
- 【转载】使用 Google Guava 美化你的 Java 代码
转载地址: https://blog.csdn.net/wisgood/article/details/13297535 原文地址:https://my.oschina.net/leejun2005/ ...
- maven命令行创建web项目报错:java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils
早上一上班就想新建一个web项目玩玩,没想到一敲命令创建就失败了,真是出师不利.各种折腾无果,当然我也可以用eclipse直接创建的,就是不甘心被这破问题给耍了.刚刚才发现问题原因,这个结果我也是醉了 ...
- Google Guava Cache 全解析
Google guava工具类的介绍和使用https://blog.csdn.net/wwwdc1012/article/details/82228458 LoadingCache缓存使用(Loadi ...
- [Google Guava] 12-数学运算
原文链接 译文链接 译者:沈义扬 范例 1 int logFloor = LongMath.log2(n, FLOOR); 2 int mustNotOverflow = IntMath.checke ...
- Apache Commons CLI官方文档翻译 —— 快速构建命令行启动模式
昨天通过几个小程序以及Hangout源码学习了CLI的基本使用,今天就来尝试翻译一下CLI的官方使用手册. 下面将会通过几个部分简单的介绍CLI在应用中的使用场景. 昨天已经联系过几个基本的命令行参数 ...
- Apache Commons CLI命令行启动
今天又看了下Hangout的源码,一般来说一个开源项目有好几种启动方式--比如可以从命令行启动,也可以从web端启动.今天就看看如何设计命令行启动... Apache Commons CLI Apac ...
- Google Guava学习笔记——简介
Google Guava是什么东西?首先要追溯到2007年的“Google Collections Library”项目,它提供对Java 集合操作的工具类.后来Guava被进化为Java程序员开发必 ...
随机推荐
- 创建pathing jar
pathing jar是一个特殊的jar: 该jar文件只包含manifest.mf文件 该manifest文件只包含Class-Path,列出了所有需要真正加到classpath中的jar,或者di ...
- Spire.Doc组件读取与写入Word
之前写了一篇开源组件DocX读写word的文章,当时时间比较匆忙选了这个组件,使用过程中还是有些不便,不能提前定义好模版,插入Form表单域进行替换.最近无意中发现Spire.Doc组件功能很强大,目 ...
- Jenkins进阶系列之——17Jenkins升级、迁移和备份
升级Jenkins Jenkins的开发迭代非常快,每周发布一个开发版本,长期支持版每半年更新一次(ps:大版本更新).如此频繁的更新,怎么升级呢? war:下载新版的war文件,替换旧版本war文件 ...
- 通过源码分析MyBatis的缓存
前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...
- 你真的熟悉background吗?
一两个月没更新博客了,因为放假刚在深圳找了实习,一直都比较忙碌,不过我觉得再忙,还是需要时间去沉淀一些东西,工作的时候别人看到的只是你有没有实现最终的结果,但自己是否思考,是否去总结,决定着你工作是否 ...
- 用js转换joson返回数据库的时间格式为/Date(*************)/
原理是取中间的毫秒数,再转换成js的Date类型 function ChangeDateFormat(val) { if (val != null) { var date = new Date(par ...
- 一些实用的sublime快捷键以及初始设置
一些常用快捷键 Ctrl + N-------------------新建 Ctrl + F-------------------查找 Ctrl+Shift +k -----------删除一行 Ct ...
- SQL2008R2 不支持用该后端版本设计数据库关系图或表
向下不兼容. 要么安装SQL2012,要么把SQL2012数据库通过脚本转成2008
- OpenFlow
What is OpenFlow? OpenFlow is an open standard that enables researchers to run experimental protocol ...
- Entity Framework 出现 "此 ObjectContext 实例已释放,不可再用于需要连接的操作" 的错误
原因 Entity的导航属性在View中使用,但是该Entity所在的Context已经在Controller中通过 using 释放掉:但是Entity又具有Deferred Query Evalu ...