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工具类的使用

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)中的工具类

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/107713.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

san.js源码解读之模版解析(parseTemplate)篇——readIdent函数

一、源码分析 /*** 读取ident* 这里的 ident 指标识符(identifier)&#xff0c;也就是通常意义上的变量名* 这里默认的变量名规则为&#xff1a;由美元符号($)、数字、字母或者下划线(_)构成的字符串** inner* param {Walker} walker 源码读取对象* return {string}*/ functio…

EtherNet Ip工业RFID读写器与欧姆龙PLC 配置示例说明

一、准备阶段 POE交换机欧姆龙PLC 支持EtherNet Ip协议CX-Programmer 9.5配置软件 二、配置读卡器 1、打开软件 2、选择网卡&#xff0c;如果多网卡的电脑请注意对应所接的网卡&#xff0c;网卡名一般为“Network adapter Realtek PCIe GBE Family” 3、点击“选择网卡”&…

IP地址与代理ip在网络安全中的关键作用

目录 前言 一、IP地址在网络安全中的作用 1、网络流量监视和分析 2、网络安全事件响应 3、网络安全检测和防御 二、代理IP在网络安全中的作用 1、流量过滤和清洗 2、匿名访问和保护隐私 3、实现全球化业务 三、IP地址和代理IP在网络安全中的应用案例 1、DDoS攻击 2…

AI新能量!FortiGate NGFW面向数据中心全面集成FortiGuard AI 安全服务

企业IT技术正在以惊人的速度发展&#xff0c;转型最大的领域之一是下一代防火墙&#xff08;NGFW&#xff09;市场。如今&#xff0c;混合云、多云、边缘等多种基础设施形态共存&#xff0c;已经成为大部分企业的常态&#xff0c;不断扩张的攻击面需要不同形态防火墙的安全防护…

Spring Security漏洞防护—HttpFirewall和 HTTPS

一、HttpFirewall Spring Security有几个领域&#xff0c;你所定义的 pattern 会针对传入的请求进行测试&#xff0c;以决定应该如何处理请求。这发生在 FilterChainProxy 决定请求应该通过哪个过滤链时&#xff0c;以及 FilterSecurityInterceptor 决定哪些安全约束适用于请求…

守牢底线——建行驻江门市分行纪检组举办2023年清廉合规大讲堂

为推动廉洁教育打通“最后一公里”&#xff0c;近日&#xff0c;建行驻江门市分行纪检组举办江门市分行2023年清廉合规大讲堂。 本次大讲堂邀请了检察院资深检察官专题讲授《金融从业人员易涉犯罪问题剖析及预防》&#xff0c;检察官结合一线办案经历&#xff0c;从防范化解金…

从零开始的LINUX(三)

bc&#xff1a;进行浮点数运算 uname&#xff1a;查看当前的操作系统 ctrlc&#xff1a;中止当前正在执行的程序 ctrld&#xff1a;退出xshell shutdown&#xff1a;关机 reboot&#xff1a;重启 shell外壳&#xff1a; 作用&#xff1a;1、命令解释&#xff08;将输入的程序…

039-第三代软件开发-PDF阅读器

第三代软件开发-PDF阅读器 文章目录 第三代软件开发-PDF阅读器项目介绍PDF阅读器1 初始化PDF view2 qml 中使用3 创建模块 关键字&#xff1a; Qt、 Qml、 pdf、 LTDev、 本地 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Met…

【vue3】样式穿透、完整新特性、动态css、css-module

一、样式穿透 vue2里面使用 /deep/ vue3里面使用 :deep() :deep(.el-input__inner){background-color: red; }二、完整新特性 :slotted() //parent.vue <template><div><p>这是父级</p><span></span><A><p class"red"…

[每周一更]-(第69期):特殊及面试的GIT问题解析

整合代码使用过程的问题&#xff0c;以及面试遇到的细节&#xff0c;汇总一些常用命令的对比解释和对比&#xff1b; 1、fetch和pull区别 git fetch是将远程主机的最新内容拉到本地&#xff0c;用户在检查了以后决定是否合并到工作本机分支中。 git pull则是将远程主机的最新内…

【Docker】联合探讨Docker:容器化技术的革命性应用

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

8.自定义组件布局和详解Context上下文

pages/index.vue layout布局运行在服务端 1、在项目的目录下新建layout文件夹&#xff0c;并新建一个blog.vue布局文件 2、在页面中的layout函数里&#xff0c;返回刚才新建布局文件的名字blog就可以使用了 export default {...layout (context) {console.log(context)retu…

ElasticSearch(ES)8.1及Kibana在docker环境下如何安装

ES基本信息介绍 Elasticsearch&#xff08;简称ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;最初由Elastic公司创建。它属于Elastic Stack&#xff08;ELK Stack&#xff09;的核心组件之一&#xff0c;用于实时地存储、检索和分析大量数据。 以下是Elastics…

37基于MATLAB平台的图像去噪,锐化,边缘检测,程序已调试通过,可直接运行。

基于MATLAB平台的图像去噪&#xff0c;锐化&#xff0c;边缘检测&#xff0c;程序已调试通过&#xff0c;可直接运行。 37matlab边缘检测图像处理 (xiaohongshu.com)

【蓝桥每日一题]-前缀和与差分(保姆级教程 篇2)#差分序列

昨天讲的概念和模板&#xff0c;今天讲一个差分序列的好题(好好体会里面的优化思想)&#xff1a; 目录 题目&#xff1a; 思路&#xff1a; 题目&#xff1a; 手动打出样例哈 输入&#xff1a; 输出&#xff1a; 4 …

吴恩达《机器学习》2-1:模型描述

一、单变量线性回归 单变量线性回归是监督学习中的一种算法&#xff0c;通常用于解决回归问题。在单变量线性回归中&#xff0c;我们有一个训练数据集&#xff0c;其中包括一组输入特征&#xff08;通常表示为&#x1d465;&#xff09;和相应的输出目标&#xff08;通常表示为…

QT中文乱码解决方案与乱码的原因

相信大家应该都遇到过中文乱码的问题&#xff0c;有时候改一改中文就不乱码了&#xff0c;但是有时候用同样的方式还是乱码&#xff0c;那么这个乱码到底是什么原因&#xff0c;又该如何彻底解决呢&#xff1f; 总结 先总结一下&#xff1a; Qt5中&#xff0c;将QString()的构…

设计模式【Iterator 模式】

Iterator 模式 1.什么是 Iterator 模式 Iterator 模式就是按照顺序遍历数据集合。 2.示例程序 1.Aggregate 接口 Aggregate 接口是要遍历的集合的接口&#xff0c;声明方法 iterator &#xff0c;实现了该接口的类可以通过 iterator 方法遍历数据集合的元素。 public int…

ab压力测试

标题相关概念 QPS&#xff0c;每秒查询 QPS&#xff1a;Queries Per Second意思是“每秒查询率”&#xff0c;是一台服务器每秒能够相应的查询次数&#xff0c;是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 互联网中&#xff0c;作为域名系统服务器的机…

论文阅读——DistilBERT

ArXiv&#xff1a;https://arxiv.org/abs/1910.01108 Train Loss: DistilBERT&#xff1a; DistilBERT具有与BERT相同的一般结构&#xff0c;层数减少2倍&#xff0c;移除token类型嵌入和pooler。从老师那里取一层来初始化学生。 The token-type embeddings and the pooler a…