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

相关推荐
小毅&Nora3 分钟前
【Java线程安全实战】⑨ CompletableFuture的高级用法:从基础到高阶,结合虚拟线程
java·线程安全·虚拟线程
冰冰菜的扣jio4 分钟前
Redis缓存中三大问题——穿透、击穿、雪崩
java·redis·缓存
PyHaVolask7 分钟前
SQL注入漏洞原理
数据库·sql
小璐猪头16 分钟前
专为 Spring Boot 设计的 Elasticsearch 日志收集 Starter
java
ptc学习者17 分钟前
黑格尔时代后崩解的辩证法
数据库
代码游侠21 分钟前
应用——智能配电箱监控系统
linux·服务器·数据库·笔记·算法·sqlite
ps酷教程36 分钟前
HttpPostRequestDecoder源码浅析
java·http·netty
闲人编程37 分钟前
消息通知系统实现:构建高可用、可扩展的企业级通知服务
java·服务器·网络·python·消息队列·异步处理·分发器
!chen41 分钟前
EF Core自定义映射PostgreSQL原生函数
数据库·postgresql
霖霖总总44 分钟前
[小技巧14]MySQL 8.0 系统变量设置全解析:SET GLOBAL、SET PERSIST 与 SET PERSIST_ONLY 的区别与应用
数据库·mysql