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:

  • checkArgument throws IllegalArgumentException
  • checkState throws IllegalStateException
  • checkNotNull throws NullPointerException
  • checkElementIndex and checkPositionIndex throw IndexOutOfBoundsException, 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的更多相关文章

  1. [Google Guava] 1.2-前置条件

    原文链接 译文链接 译者: 沈义扬 前置条件:让方法调用的前置条件判断更简单. Guava在Preconditions类中提供了若干前置条件判断的实用方法,我们强烈建议在Eclipse中静态导入这些方 ...

  2. 使用 Google Guava 美化你的 Java 代码

    文章转载自:http://my.oschina.net/leejun2005/blog/172328 目录:[ - ] 1-使用 GOOGLE COLLECTIONS,GUAVA,STATIC IMP ...

  3. 【转载】使用 Google Guava 美化你的 Java 代码

    转载地址: https://blog.csdn.net/wisgood/article/details/13297535 原文地址:https://my.oschina.net/leejun2005/ ...

  4. maven命令行创建web项目报错:java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils

    早上一上班就想新建一个web项目玩玩,没想到一敲命令创建就失败了,真是出师不利.各种折腾无果,当然我也可以用eclipse直接创建的,就是不甘心被这破问题给耍了.刚刚才发现问题原因,这个结果我也是醉了 ...

  5. Google Guava Cache 全解析

    Google guava工具类的介绍和使用https://blog.csdn.net/wwwdc1012/article/details/82228458 LoadingCache缓存使用(Loadi ...

  6. [Google Guava] 12-数学运算

    原文链接 译文链接 译者:沈义扬 范例 1 int logFloor = LongMath.log2(n, FLOOR); 2 int mustNotOverflow = IntMath.checke ...

  7. Apache Commons CLI官方文档翻译 —— 快速构建命令行启动模式

    昨天通过几个小程序以及Hangout源码学习了CLI的基本使用,今天就来尝试翻译一下CLI的官方使用手册. 下面将会通过几个部分简单的介绍CLI在应用中的使用场景. 昨天已经联系过几个基本的命令行参数 ...

  8. Apache Commons CLI命令行启动

    今天又看了下Hangout的源码,一般来说一个开源项目有好几种启动方式--比如可以从命令行启动,也可以从web端启动.今天就看看如何设计命令行启动... Apache Commons CLI Apac ...

  9. Google Guava学习笔记——简介

    Google Guava是什么东西?首先要追溯到2007年的“Google Collections Library”项目,它提供对Java 集合操作的工具类.后来Guava被进化为Java程序员开发必 ...

随机推荐

  1. JAVA CDI 学习(3) - @Produces及@Disposes

    上一节学习了注入Bean的生命周期,今天再来看看另一个话题: Bean的生产(@Produces)及销毁(@Disposes),这有点象设计模式中的工厂模式.在正式学习这个之前,先来看一个场景: 基于 ...

  2. 最清晰的Android多屏幕适配方案

    问题的引入 当您的Android应用即将发布的时候,如果你想让更多的用户去使用你的应用,摆在工程师面前的一个重要问题就是如何让你的应用能在各种各样的终端上运行,这里的各种各样首当其冲的就是不同的屏幕分 ...

  3. 理解JavaScript的作用域链

    上一篇文章中介绍了Execution Context中的三个重要部分:VO/AO,scope chain和this,并详细的介绍了VO/AO在JavaScript代码执行中的表现. 本文就看看Exec ...

  4. JavaScript函数劫持

    一.为什么我会写这篇文章 这篇文章其实是在一个偶然的机会下发现了居然有JavaScript劫持这种东西,虽然这种东西在平时用的比较少,而且一般实用价值不高,但是在一些特殊的情况下还是要使用到的,所以在 ...

  5. sql server 事务处理

    事物处理   事务是SQL Server中的单个逻辑单元,一个事务内的所有SQL语句作为一个整体执行,要么全部执行,要么都不执行. 事务有4个属性,称为ACID(原子性.一致性.隔离性和持久性)   ...

  6. STM32 C语言,端口映射

    static XX 有记忆的定义 typedef XX 可以多次定义一个 #ifedf XXX XXX(程序段1) #else XXX(程序段2)

  7. 维特比算法(Viterbi Algorithm)

      寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states) 对于一个特殊的隐马尔科夫模型(HMM)及一个相应的观察序列,我们常常希望 ...

  8. 手机信号强度单位dB、dBm和asu

    dB.dBm都是功率增益的单位,不同之处如下: dB是一个表征相对值的值,纯粹的比值,只表示两个量的相对大小关系,没有单位,当考虑甲的功率相比于乙功率大或小多少个dB时,按下面的计算公式:10log( ...

  9. 【转】css布局居中和CSS内容居中区别和对应DIV CSS代码

    原文地址:http://www.divcss5.com/jiqiao/j771.shtml css布局居中和CSS内容居中区别和对应DIV CSS代码教程与图文代码案例篇 对于新手来说DIV CSS布 ...

  10. 【BZOJ 1031】【JSOI 2007】字符加密Cipher

    后缀数组模板题,看了一天的后缀数组啊,我怎么这么弱TwT #include<cstdio> #include<cstring> #include<algorithm> ...