zoukankan      html  css  js  c++  java
  • Google Guava之Preconditions

    文中所述Guava版本基于29.0-jre,文中涉及到的代码完整示例请移步Github查看。

    如何编写参数条件判定语句

    在我们编写一些方法的时候,都需要对方法传入的参数进行一些条件限定,比如

    /**
     * 以自然顺序比较两个字符串并返回较大的字符串
     */
    public String compare(String firstString, String secondString) {
        if (firstString == null) {
            throw new NullPointerException("Argument 'firstString' expected non-null");
        }
        if (secondString == null) {
            throw new NullPointerException("Argument 'secondString' expected non-null");
        }
        if (firstString.compareTo(secondString) >= 0) {
            return firstString;
        }
        return secondString;
    }
    

    这样当条件不满足的时候,就会打印出对应的异常,能够帮助我们快速定位错误原因,但是如果每个参数都需要编写类似这样if判断的语句,就让代码很臃肿。Guava提供一个工具类,帮助我们方便的值进行条件判定。

    /**
     * 以自然顺序比较两个字符串并返回较大的字符串
     */
    public String compareSimple(String firstString, String secondString) {
        Preconditions.checkNotNull(firstString, "Argument 'firstString' expected non-null");
        Preconditions.checkNotNull(secondString, "Argument 'secondString' expected non-null");
        if (firstString.compareTo(secondString) >= 0) {
            return firstString;
        }
        return secondString;
    }
    

    这样将原本需要if判断的代码语句简化为单条Preconditions语句,其实Preconditions也就是替我们做了if的判断,checkNotNull的源代码如下

    @CanIgnoreReturnValue
    public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) {
        if (reference == null) {
            throw new NullPointerException(String.valueOf(errorMessage));
        } else {
            return reference;
        }
    }
    

    java.util包中也有实现类似功能的工具类,就是java.util.Objects,我们来看下java.util.Objects的用法

    Objects.requireNonNull(secondString, "Argument 'secondString' expected non-null");
    

    既然已经有了类似的方法,为什么Guava还要重复造轮子呢?原因在于java.util.Objects提供的条件判定方案太少,另外Guava提供更方便的异常信息打印(Preconditions提供可变参数列表,可供我们打印多余信息,比如可以在条件不满足时打印上下文变量值,下文可看到在条件不满足时打印出方法所有参数值)。

    但是我仍认为Preconditions提供的功能不是很完美,首先Preconditions.checkNotNull(firstString)只有单个参数时,如果firstString为null,则打印的时没有异常信息的空指针异常,这导致我们想要获取异常详细信息都需要自己来编写异常提示信息

    java.lang.NullPointerException
    	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:878)
    

    我希望Preconditions提供的条件判定语句在只提供单个参数时,能够自己组织一条有意义的异常提示信息。

    另外如果对于某个参数需要多重条件判断,比如我们判定参数firstString既要不为null,也要长度大于5,这时候就需要写两条Preconditions语句

    /**
     * 以自然顺序比较两个字符串并返回较大的字符串
     */
    public String compareSimple(String firstString, String secondString) {
        Preconditions.checkNotNull(firstString, "Argument 'firstString' expected non-null", firstString, secondString);
        Preconditions.checkArgument(firstString.length() > 5, "Argument 'firstString' expected length > 5", firstString, secondString);
        Preconditions.checkNotNull(secondString, "Argument 'secondString' expected non-null");
        if (firstString.compareTo(secondString) >= 0) {
            return firstString;
        }
        return secondString;
    }
    
    
    // caller
    compareSimple("test", "test");
    
    
    // output
    java.lang.IllegalArgumentException: Argument 'firstString' expected length > 5 [test, test]
    

    我们也可以把两条Preconditions语句合为单条

    Preconditions.checkArgument(firstString != null && firstString.length() > 5, "Argument 'firstString' expected non-null and length > 5", firstString, secondString);
    

    但是这种情况下当参数为null或者长度小于5时,打印相同的信息,不利于我们对失败原因的判定,建议Guava在以后能够提供满足多条件判定的Preconditions语句

    Preconditions提供的方法

    方法签名 描述 失败时抛出的异常
    checkArgument(boolean) 检查条件判定的布尔值是否是true,用来判定方法的参数。 IllegalArgumentException
    checkNotNull(T) 检查值是否为null,不为null则返回该值。 NullPointerException
    checkState(boolean) 检查对象的某些状态,不依赖于方法参数。例如,一个Iterator可能会使用它来检查在调用remove之前是否已调用next。 IllegalStateException
    checkElementIndex(int index, int size) 检查索引是否为列表,字符串或数组的有效元素索引。元素索引可能是[0, size),不需要把列表,字符串或数组作为参数传递,直接传递它的size。返该方法返回值为index。 IndexOutOfBoundsException
    checkPositionIndex(int index, int size) 检查索引是否为列表,字符串或数组的有效元素索引。元素索引可能是[0, size],不需要把列表,字符串或数组作为参数传递,直接传递它的size。返该方法返回值为index。 IndexOutOfBoundsException
    checkPositionIndexes(int start, int end, int size) 检查[start, end)是否是列表,字符串或数组的有效子范围。返回代码自组织的错误信息。 IndexOutOfBoundsException

    参考

  • 相关阅读:
    mysql 常用命令集锦
    linux系统端口查看和占用的解决方案
    Linux 基本命令
    Linux 内存优化
    maven 常用脚本
    linux 下maven安装
    MYSQL创建用户Unknown column 'plugin' in 'mysql.user'的解决方法
    mysql 安装及卸载 主从配置
    排序算法
    JDK和JRE的区别
  • 原文地址:https://www.cnblogs.com/weegee/p/12955124.html
Copyright © 2011-2022 走看看