Android Studio开发中Preconditions类的应用

AIV.WU 提交于 周三, 12/04/2019 - 03:20

有一段时间没写Blog了,忙这忙那的,今天来谈谈Preconditions的前置条件判断吧。

在日常开发中,经常会遇到要对输入参数进行核验的情况,比如是否为空,参数的取值范围是否符合要求等等。单独进行校验的话,代码的重复率就很高了。这时我们可以用Preconditions类来统一校验参数,同时可以选择抛出对应的异常信息,让代码看起来更明了。

Preconditions类中提供了若干前置条件判断的静态方法,每个方法都有三种方式: 
*   没有额外参数:抛出的异常中没有错误消息; 
*   用一Object对象作为error message参数:使用Object.toString() 抛出异常错误消息; 
*   用字符串作为替换带有占位符的error message参数,类似于printf,但考虑GWT的兼容性和效率,只支持%s指示符。

例如

checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
checkArgument(i < j, "Expected i < j, but %s > %s", i, j);

方法:

checkNotNull、checkArgument和checkState有大量的重载,它们采用可变参数方式。 

  • checkArgument(boolean)
    检查boolean是否为true,用来检查传递给方法的参数。失败IllegalArgumentException

  • // Without an Error Message
    public void test() {
        int age = -7;
        Preconditions.checkArgument(age > 0);
    }
    
    // With an Error Message
    public void test() {
        int age = -7;
        String message = "Age can't be zero or less than zero.";
    Preconditions.checkArgument(age > 0, message);
    }
    
    // With a Template Error Message
    public void test() {
        int age = -7;
        String message = "Age should be positive number, you supplied %s.";
    Preconditions.checkArgument(age > 0, message, age);
    }
  • checkNotNull(T)
    检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNull。失败NullPointerException

  • public void test() {
        String nullObject = null;
        String message = "Please check the Object supplied, its null!";
      
    Preconditions.checkNotNull(nullObject, message);
    }
    
    public void test() {
        String nullObject = null;
        String message = "Please check the Object supplied, its %s!";
      
    Preconditions.checkNotNull(nullObject, message,new Object[] { null });
    }
  • checkState(boolean)
    检查对象的一些状态,不依赖方法参数。例如,Iterator可以用来next是否在remove之前被调用。
    用来检查对象的某些状态。失败IllegalStateException

  • public void test() {
        int[] validStates = { -1, 0, 1 };
        int givenState = 9;
        String message = "You have entered an invalid state";
      
    Preconditions.checkState(Arrays.binarySearch(validStates, givenState) > 0, message);
    }

以下方法无需直接传入list, string或array, 只需传入大小。

  • checkElementIndex(int index, int size)
    检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index< size,返回index。
    失败IndexOutOfBoundsException,数组越界的时候需要这个

  • public void test() {
        int[] numbers = { 1, 2, 3, 4, 5 };
        String message = "Please check the bound of an array and retry";
      
    Preconditions.checkElementIndex(6, numbers.length - 1, message);
    }
  • checkPositionIndex(int index, int size)
    检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size。返回index。
    失败 IndexOutOfBoundsException

  • public void test() {
        int[] numbers = { 1, 2, 3, 4, 5 };
        String message = "Please check the bound of an array and retry";
      
    Preconditions.checkPositionIndex(6, numbers.length - 1, message);
    }
  • checkPositionIndexes(int start, int end, int size)
    检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效,失败IndexOutOfBoundsException

  • public void test() {
        int start = 1;
        int end = 6;
        int[] numbers = { 1, 2, 3, 4, 5 };
    
    Preconditions.checkPositionIndexes(start, end, numbers.length);
    }

总结一下

  • Preconditions类的方法非常简单明了。比如checkNotNull清楚地描述做了什么,会抛出什么异常;并且直接返回检查的参数,让你可以在构造函数中保持字段的单行赋值风格:this.field = checkNotNull(field)。

  • 索引值常用来查找列表、字符串或数组中的元素,如List.get(int), String.charAt(int)

  • 位置值和位置范围常用来截取列表、字符串或数组,如List.subList(int,int), String.substring(int)

  • 简单、可自定义参数的异常信息。

 

类别