Preconditions是guava提供的用于进行代码校验的工具类,其中提供了许多重要的静态校验方法,用来简化我们工作或开发中对代码的校验或预处理,能够确保代码符合我们的期望,并且能够在不符合校验条件的地方,准确的为我们显示出问题所在,接下来,我们就来学习使用Preconditions进行代码校验。

Preconditions是guava提供的用于进行代码校验的工具类,其中提供了许多重要的静态校验方法,用来简化我们工作或开发中对代码的校验或预 处理,能够确保代码符合我们的期望,并且能够在不符合校验条件的地方,准确的为我们显示出问题所在,接下来,我们就来学习使用Preconditions 进行代码校验。

看看我们之前是怎么进行参数判断的。

 int[] intArray = {1, 2, 3, 4, 5, 6};

    private void testPreconditions(boolean preCondition, int[] array, int position) {
        if (!preCondition) {
            throw new IllegalArgumentException("preCondition not allow!!");
        }
        if (array == null) {
            throw new NullPointerException("array is null!!");
        }
        if (array.length == 0) {
            throw new IllegalArgumentException("array length is 0!!");
        }
        if (position > array.length || position < 0) {
            throw new ArrayIndexOutOfBoundsException("position error!!");
        }
        //do something...

    }

这里看起来没什么,但是如果我这个类很大,方法很多呢?看到全篇都是if(XX==null) throw{...}作何感想。
下面我们看看如果用Preconditions做前置判断

private void testPreconditions(boolean preCondition, int[] array, int position) 
    {
        Preconditions.checkArgument(preCondition);
        Preconditions.checkNotNull(array);
        Preconditions.checkElementIndex(position, array.length, "position error!");
          //do something...
    }

是不是清爽多了,使用Preconditions可以更清晰的表达程序意图。

为什么要使用Preconditions

那么你可能会问,为啥要用Preconditions,如果是空指针在用的时候,他自己就会抛出异常啊。
但是我们期望的是尽早抛出异常,而不是等到数据被层层传递,传递到非常深的位置,这样浪费系统资源更不利于我们开发精确定位错误。
所以推荐在方法的入口,或运算开始前,先检查数据
例如:

int length = datas.get(5).getDescription().concat("XX").split(",").length;

像这种代码,就算抛出空指针也不知道到底是那个对象空指针了,需要一步一步调试

这就是Preconditions另一个作用:尽早发现错误,精确控制出错的位置

guava的诞生旨在对Java Collection进行扩展以提高开发效率,但是随着多年的发展它已经覆盖到了Java开发的方方面面,在Java 8中,已经可以看到不少API就是从Guava中原封不动的借鉴而来。
例如,初始化一个集合,使用JDK这么做

//JDK
List<String> list = new ArrayList<String>(); 
list.add("a");
list.add("b");
list.add("c");
list.add("d");

但是使用Guava,可以很简洁的表达

//Guava
List<String> list = Lists.newArrayList("a", "b", "c", "d");

但是这个库中包含大约14k的方法数,是个很大的库,这里我们只需要他的Preconditions这个类就行了。

校验的方法有14个

翻开Preconditions的源码,我们看到,guava进行了大量方法的重载,组成了Preconditions工具类,下面我们先简单的了解一下,所有的14个静态方法,如下:

checkArgument(boolean expression):用来校验表达式是否为真,一般用作方法中校验参数

checkArgument(boolean expression, @Nullable Object errorMessage):校验表达式是否为真,不为真时显示指定的错误信息。

checkArgument(boolean expression, @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs):校验表达式是否为真,不为真时显示错误信息,错误信息中允许使用占位符。

checkState(boolean expression):校验表达式是否为真,一般用作校验方法返回是否为真。

checkState(boolean expression, @Nullable Object errorMessage):当表达式为假的时候,显示指定的错误信息。

checkState(boolean expression,@Nullable String errorMessageTemplate,@Nullable Object... errorMessageArgs):允许在错误信息中使用占位符。

checkNotNull(T reference):校验对象是否为空。

checkNotNull(T reference, @Nullable Object errorMessage):对象为空时显示指定的错误信息。

checkNotNull(T reference, @Nullable String errorMessageTemplate,@Nullable Object... errorMessageArgs):允许在错误信息中使用占位符。

checkElementIndex( int index, int size, @Nullable String desc):校验元素的索引值是否有效,index大于等于0小于size,在无效时显示错误描述信息。

checkElementIndex(int index, int size):错误描述信息为“index”

checkPositionIndex(int index, int size, @Nullable String desc):校验元素的索引值是否有效,index大于等于0小于等于size,在无效时显示错误描述信息。

checkPositionIndex(int index, int size):错误描述信息为“index”

checkPositionIndexes(int start, int end, int size):校验大于等于start,小于end的list的长度是否为size。