这几天看Fresco和Glide的代码,发现他们都使用了Preconditions来做前置判断条件,发现这样写,代码变得既优雅又容易调试。 Preconditions的用法
OK,先看看平常写代码我们是怎么做的参数判断。
判断参数,如果参数配置错误,就抛出异常
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另一个作用:尽早发现错误,精确控制出错的位置 抽取Preconditions
/**
* Created by lgq on 16-1-5.
*/
public class TestPreconditions {
/**
* 前置条件检查,当条件不满足时,就会抛出异常
*/
@Test
public void testPreconditions(){
String constantName = null;
//Preconditions.checkNotNull(constantName,"constantName 为 null");
String str = "abc";
Preconditions.checkNotNull(str,"str 为 null"); // 不会输出
int age = 23;
Integer number = 12;
//Preconditions.checkArgument(age < 20, "age 必须要< 20");
Preconditions.checkArgument(number < 20, "number 必须要< 20");
List<Integer> integerList = Lists.newArrayList(3,5,6,98,2,45);
for(int i=0; i<integerList.size(); i++) {
// 检查数组下标是否越界
int passIndex = Preconditions.checkElementIndex(i, integerList.size());
//System.out.println("下标:"+ passIndex + " ==> 满足要求");
}
// 检查下标值7 是否在集合integerList中
//Preconditions.checkElementIndex(7, integerList.size());
//Preconditions.checkPositionIndex(8, integerList.size());
Preconditions.checkPositionIndexes(2, 4, integerList.size());
// 判断是否为true,当为false时,会抛出IllegalStateException
Preconditions.checkState(4 < 3);
}
}