SpringBoot内置工具类之断言Assert的使用与部分解析

先例举一个service的demo中用来验证参数对象的封装方法,使用了Assert工具类后是不是比普通的 if(xxx) { throw new RuntimeException(msg) } 看上去要简洁多了?

断言Assert工具类简介

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

断言Assert工具类的使用

java 复制代码
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("全部断言成功~!");
  }

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

java 复制代码
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工具类的部分源码

java 复制代码
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)中的工具类

参考:SpringBoot内置工具类之 断言 Assert

相关推荐
怕什么真理无穷5 分钟前
mysql server 9.4 windows安装教程(sqlyog 下载)
数据库
Olrookie11 分钟前
MySQL运维常用SQL
运维·数据库·sql·mysql·dba
货拉拉技术17 分钟前
网关 MCP 转换技术:从实现到平台落地
java·架构·mcp
艾菜籽18 分钟前
SpringMVC练习:加法计算器与登录
java·spring boot·spring·mvc
数据库生产实战21 分钟前
ORACLE 19C ADG环境 如何快速删除1.8TB的分区表?有哪些注意事项?
数据库·oracle
blackorbird38 分钟前
使用 Overpass Turbo 查找监控摄像头
运维·服务器·数据库·windows
IT永勇42 分钟前
SQLite数据库基本操作
数据库·sqlite·嵌入式开发·增删改查·关系型数据库
洋不写bug44 分钟前
数据库的创建,查看,修改,删除,字符集编码和校验操作
android·数据库·adb
LawsonJin1 小时前
springboot实现微信小程序支付(服务商和普通商户模式)
spring boot·后端·微信小程序
浮游本尊1 小时前
Java学习第25天 - Spring Cloud Alibaba微服务生态
java