美文网首页
SpringBoot内置工具类之 断言 Assert

SpringBoot内置工具类之 断言 Assert

作者: 程就人生 | 来源:发表于2022-07-16 13:24 被阅读0次

    说到断言Assert,我们在查看源码时经常看到,它是使用比较频繁的一个工具类,但我也经常忽略它的存在。现在就让我们一起看看它吧!

    About断言Assert

    1. 断言是一个判断逻辑,用来检查不该发生的情况;
    2. 断言的判定规则:
      2.1.值为true时,程序从断言语句处继续执行;
      2.2.值为false时,程序从断言语句处抛出异常,停止执行;
      3.早在JDK的1.4版本已经引入断言assert,通过命令-enableassertions开启,通过命令-disableassertions关闭;不加参数,全局生效;加了参数,只在某个类中使用;具体可通过java help命令查看;
    3. Springframework框架中也提供了断言工具类Assert,通常用于数据合法性验证。我们今天说的就是它。

    断言Assert工具类的使用

    public static void main(String[] argo){
        
        Object obj = null;
        
        Assert.isNull(obj, "对象必须为NULL,否则抛异常不予放行");
        
        Assert.notNull(new Object(), "对象不能为NULL,否则抛异常不予放行");
        
        Assert.state(true, "参数必须为true,否则抛异常不予放行");
        
        Assert.isTrue(true, "参数必须为true,否则抛异常不予放行");
        
        // null 或 空字符串 断言失败,空格断言成功
        Assert.hasLength(" ", "参数必须有长度,否则抛异常不予放行");
        // null、空字符串、纯空格断言失败
        Assert.hasText("  dd", "参数必须有正文,否则抛异常不予放行");
        
        Assert.doesNotContain("text", "bb", "第一个参数不能包含第二个参数,否则抛异常不予放行");
        
        Object[] objArray = {true, false,};
        // 除了对象数组,还有其他类型的数组,在此不在一一举例
        Assert.notEmpty(objArray, "对象数组不能为空,否则抛异常不予放行");
        
        Assert.noNullElements(objArray, "对象数组中不能有null元素,否则抛异常不予放行");
        
        Map<String,String> map = new HashMap<String,String>();
        
        Assert.isInstanceOf(Map.class, map, "第二个参数必须是第一个参数的实例,否则抛异常不予放行");
        
        Assert.isAssignable(Map.class, List.class, "第二个参数必须是第一个参数的子类或者实现类,否则抛异常不予放行");    
        
        System.out.println("全部断言成功~!");
      }
    

    把最后一个断言设置失败时,失败的语句处抛出异常,程序在此处终止运行,运行结果如下所示:

    Exception in thread "main" java.lang.IllegalArgumentException: 第二个参数必须是第一个参数的子类或者实现类,否则抛异常不予放行: interface java.util.List
      at org.springframework.util.Assert.assignableCheckFailed(Assert.java:720)
      at org.springframework.util.Assert.isAssignable(Assert.java:651)
      at com.example.util.SpringUtilTest.main(SpringUtilTest.java:40)
    

    一起看下 Assert工具类的部分源码

    import java.util.Collection;
    import java.util.Map;
    import java.util.function.Supplier;
    
    import org.springframework.lang.Nullable;
    import org.springframework.util.CollectionUtils;
    import org.springframework.util.ObjectUtils;
    import org.springframework.util.StringUtils;
    
    /**
     * 断言工具类类
     * SpringBoot 2.1.4.RELEASE
     * 符合条件就继续执行,否则抛异常不予放行
     */
    public abstract class Assert {
    
      /**
       * 参数expression必须为true,否则抛异常,不予放行
       * @param expression boolean型表达式
       * @param message 用于定制异常消息内容
       */
      public static void state(boolean expression, String message) {
        if (!expression) {
          throw new IllegalStateException(message);
        }
      }
    
      /**
       * 参数expression必须为true,否则抛异常,不予放行
       * @param expression
       * @param message
       */
      public static void isTrue(boolean expression, String message) {
        if (!expression) {
          throw new IllegalArgumentException(message);
        }
      }
    
      /**
       * 要求对象object必须为null,否则抛异常,不予放行
       * @param object
       * @param message
       */
      public static void isNull(@Nullable Object object, String message) {
        if (object != null) {
          throw new IllegalArgumentException(message);
        }
      }
      
      /**
       * 要求参数object不为null,否则抛异常,不予放行;
       * 和isNull() 方法相反
       * @param object
       * @param message
       */
      public static void notNull(@Nullable Object object, String message) {
        if (object == null) {
          throw new IllegalArgumentException(message);
        }
      }
    
      /**
       * 要求参数text必须有长度,不为null且长度大于0,否则抛异常,不予放行
       * @param text 字符串文本
       * @param message
       */
      public static void hasLength(@Nullable String text, String message) {
        if (!StringUtils.hasLength(text)) {
          throw new IllegalArgumentException(message);
        }
      }
    
      /**
       * 要求参数text必须有内容,否则抛异常,不予放行
       * @param text 字符串文本
       * @param message
       */
      public static void hasText(@Nullable String text, String message) {
        if (!StringUtils.hasText(text)) {
          throw new IllegalArgumentException(message);
        }
      }
    
      /**
       * 要求textToSearch不包含substring,否则抛异常,不予放行
       * @param textToSearch 要检索的字符串文本
       * @param substring 被检索字符
       * @param message
       */
      public static void doesNotContain(@Nullable String textToSearch, String substring, String message) {
        if (StringUtils.hasLength(textToSearch) && StringUtils.hasLength(substring) &&
            textToSearch.contains(substring)) {
          throw new IllegalArgumentException(message);
        }
      }
    
      /**
       * 要求参数array不为null,否则抛异常,不予放行
       * @param array 对象数组
       * @param message
       */
      public static void notEmpty(@Nullable Object[] array, String message) {
        if (ObjectUtils.isEmpty(array)) {
          throw new IllegalArgumentException(message);
        }
      }
      
      /**
       * 要求对象数组array中没有Null元素,否则抛异常,不予放行
       * @param array
       * @param message
       */
      public static void noNullElements(@Nullable Object[] array, String message) {
        if (array != null) {
          for (Object element : array) {
            if (element == null) {
              throw new IllegalArgumentException(message);
            }
          }
        }
      }
      
      /**
       * 要求集合collection不为null、不为空集合,否则抛异常,不予放行
       * @param collection
       * @param message
       */
      public static void notEmpty(@Nullable Collection<?> collection, String message) {
        if (CollectionUtils.isEmpty(collection)) {
          throw new IllegalArgumentException(message);
        }
      }
    
      /**
       * 要求Map集合不为null,不为空集合,否则抛异常,不予放行
       * @param map the map to check
       * @param message the exception message to use if the assertion fails
       * @throws IllegalArgumentException if the map is {@code null} or contains no entries
       */
      public static void notEmpty(@Nullable Map<?, ?> map, String message) {
        if (CollectionUtils.isEmpty(map)) {
          throw new IllegalArgumentException(message);
        }
      }
      
      /**
       * 要求对象obj必须是指定类type的实例,否则抛异常,不予放行
       * @param type
       * @param obj
       * @param message
       */
      public static void isInstanceOf(Class<?> type, @Nullable Object obj, String message) {
        notNull(type, "Type to check against must not be null");
        if (!type.isInstance(obj)) {
          instanceCheckFailed(type, obj, message);
        }
      }
    
      /**
       * 要求对象obj必须是指定类type的实例,否则抛异常,不予放行
       * @param type 
       * @param obj
       * @param message
       */
      public static void isInstanceOf(Class<?> type, @Nullable Object obj) {
        isInstanceOf(type, obj, "");
      }
    
      /**
       * 要求参数subType必须是参数superType的子类或者实现类,否则抛出异常,不予放行
       * @param superType
       * @param subType
       * @param message
       */
      public static void isAssignable(Class<?> superType, @Nullable Class<?> subType, String message) {
        notNull(superType, "Super type to check against must not be null");
        if (subType == null || !superType.isAssignableFrom(subType)) {
          assignableCheckFailed(superType, subType, message);
        }
      }
    
      /**
       * 要求参数subType必须是参数superType的子类或者实现类,否则抛出异常,不予放行
       * @param superType
       * @param subType
       * @param message
       */
      public static void isAssignable(Class<?> superType, Class<?> subType) {
        isAssignable(superType, subType, "");
      }
      
      private static void instanceCheckFailed(Class<?> type, @Nullable Object obj, @Nullable String msg) {
        String className = (obj != null ? obj.getClass().getName() : "null");
        String result = "";
        boolean defaultMessage = true;
        if (StringUtils.hasLength(msg)) {
          if (endsWithSeparator(msg)) {
            result = msg + " ";
          }
          else {
            result = messageWithTypeName(msg, className);
            defaultMessage = false;
          }
        }
        if (defaultMessage) {
          result = result + ("Object of class [" + className + "] must be an instance of " + type);
        }
        throw new IllegalArgumentException(result);
      }
    
      private static void assignableCheckFailed(Class<?> superType, @Nullable Class<?> subType, @Nullable String msg) {
        String result = "";
        boolean defaultMessage = true;
        if (StringUtils.hasLength(msg)) {
          if (endsWithSeparator(msg)) {
            result = msg + " ";
          }
          else {
            result = messageWithTypeName(msg, subType);
            defaultMessage = false;
          }
        }
        if (defaultMessage) {
          result = result + (subType + " is not assignable to " + superType);
        }
        throw new IllegalArgumentException(result);
      }
    
      private static boolean endsWithSeparator(String msg) {
        return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith("."));
      }
    
      private static String messageWithTypeName(String msg, @Nullable Object typeName) {
        return msg + (msg.endsWith(" ") ? "" : ": ") + typeName;
      }
    
      @Nullable
      private static String nullSafeGet(@Nullable Supplier<String> messageSupplier) {
        return (messageSupplier != null ? messageSupplier.get() : null);
      }
    }
    

    源码看后,好像并没有什么特别之处,验证失败就抛出异常,终止代码的执行。

    最后总结

    Assert工具类中大约有30多个静态方法供外部类调用,它的特点就是符合条件继续执行,否则抛出IllegalArgumentException异常。这个工具类是Spring框架util包(org.springframework.util)中的工具类,把这个工具类看过一遍以后,你有什么启发吗?

    突然想重写Service,来一个优雅的异常处理。

    相关文章

      网友评论

          本文标题:SpringBoot内置工具类之 断言 Assert

          本文链接:https://www.haomeiwen.com/subject/ojmhirtx.html