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

2023.10.29更新:

使用assert的不利之处:

1、assert关键字需要在运行时候显式开启才能生效,否则你的断言就没有任何意义。而现在主流的Java IDE工具默认都没有开启-ea断言检查功能。这就意味着你如果使用IDE工具编码,调试运行时候会有一定的麻烦。并且,对于Java Web应用,程序代码都是部署在容器里面,你没法直接去控制程序的运行,如果一定要开启-ea的开关,则需要更改Web容器的运行配置参数。这对程序的移植和部署都带来很大的不便。

2、用assert代替if是陷阱之二。assert的判断和if语句差不多,但两者的作用有着本质的区别:assert关键字本意上是为测试调试程序时使用的,但如果不小心用assert来控制了程序的业务流程,那在测试调试结束后去掉assert关键字就意味着修改了程序的正常的逻辑。

3、assert断言失败将面临程序的退出。这在一个生产环境下的应用是绝不能容忍的。一般都是通过异常处理来解决程序中潜在的错误。但是使用断言就很危险,一旦失败系统就挂了。

因此, 应当避免在Java中使用assert关键字,除非哪一天Java默认支持开启-ea的开关,这时候可以考虑。对比一下,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.Listat 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;}@Nullableprivate 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.mzph.cn/news/124485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET WebApi 极简依赖注入

文章目录 环境服务类启动项注入使用依赖注入的优点 环境 .NET Core 7.0ASP.NET CoreVisual Studio 2022 服务类 public class T_TempService {public T_TempService(){}public void Test(){}}启动项注入 #region 依赖注入 builder.Services.AddTransient<T_TempService&g…

滑动窗口限流算法实现一

固定算法 原理&#xff1a;固定算法是将时间线分隔成固定大小的时间窗口&#xff0c;每个窗口都会有个计数器&#xff0c;用来记录窗口时间范围内的请求总数&#xff0c;如果窗口的请求总数达到最大限定值&#xff0c;会认定流量超限。比如将窗口大小设为1分钟&#xff0c;每分…

科大讯飞勾勒生成式AI输入法“模样”,开启下一代输入法革命

回顾国内第三方输入法赛道近十余年的发展&#xff0c;移动互联网的市场红利催生了科大讯飞、百度、搜狗等颇具规模和实力的头部厂商。与此同时&#xff0c;历经多年、多方角逐&#xff0c;第三方输入法市场进入存量阶段&#xff0c;升级技术、优化用户体验来挖掘存量&#xff0…

Rest风格基本语法与实战

1&#xff0c;前置知识点 1.1 GetMapping&#xff0c;PostMapping&#xff0c;PutMapping&#xff0c;DeleteMapping 平时我们都是使用RequestMapping&#xff0c;然后通过它的method属性来指定请求的方式&#xff0c;这样是有些麻烦的&#xff0c;然后这四个标签就是来简化这…

MySQL安装『适用于 CentOS 7』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; MySQL 学习 &#x1f383;操作环境&#xff1a; CentOS 7.6 腾讯云远程服务器 &#x1f381;软件版本&#xff1a; MySQL 5.7.44 文章目录 1.MySQL 的清理与安装1.1查看是否存在 MySQL 服务1.2.卸载原有服务1.…

JS逆向基础之反调试

JS逆向基础之反调试 截至目前的话大家应该都知道我们在进行js逆向的时候需要打开浏览器开发者工具进行网页的调试&#xff0c;但是在有时候网站会阻止我们去调试它的代码&#xff0c;而其阻止我们的手段也是多种多样的。接下来我们就来简单了解一下逆向过程中常见的反调试手段…

keealived安装配置启动

1.keepalived作用和原理图 keepalived作用:解决单点故障简单原理图1: 2.keepalived安装配置启动 地址: https://www.keepalived.org/download.html# 1)解压 tar -zxvf keepalived-2.0.18.tar.gz # 2)进入keepalived目录 cd keepalived-2.0.18/ # 3)安装libnl/libnl-3依赖…

chat gpt 在开发当中的应用

chatgpt 出来已经有一段时间了&#xff0c;本人在开发的过程中也是有去使用。 经常使用的是讯飞大模型和通义千问&#xff0c;在使用的过程中&#xff0c;个人感觉讯飞大模型在写代码方面会比较智能。 比如问一个 sqlser 单表 数据量 几个亿如何处理的问题&#xff0c;讯飞会给…

C/C++ 飞翔的小鸟

载入问题&#xff1a; 解决之后效果&#xff1a; 放在main函数里面进行封装&#xff1a; 效果展示: 实现下坠 放进while&#xff08;1&#xff09;里面不断进入循环&#xff0c;每次进入循环&#xff0c;鸟的y坐标值就会发生变化&#xff0c;以此实现下下坠效果 效果展示&#…

Vue 数据绑定 和 数据渲染

目录 一、Vue快速入门 1.简介 : 2.MVVM : 3.准备工作 : 二、数据绑定 1.实例 : 2.验证 : 三、数据渲染 1.单向渲染 : 2.双向渲染 : 一、Vue快速入门 1.简介 : (1) Vue[/vju/]&#xff0c;是Vue.js的简称&#xff0c;是一个前端框架&#xff0c;常用于构建前端用户…

Flutter FittedBox

&#x1f525; 英文单词FittedBox &#x1f525; Fitted 通过有道翻译如下 &#xff1a; Box 通过有道翻译如下 &#xff1a; 对 FittedBox 的理解 我们可以将 FittedBox 理解为合适的盒子&#xff0c;将其它布局放到FittedBox这样一个盒子中&#xff0c;从而实现 盒子里面的…

kubernetes实验挑战二(troubleshoot pv pvc )

This 2-Node Kubernetes cluster is broken! Troubleshoot, fix the cluster issues and then deploy the objects according to the given architecture diagram to unlock our Image Gallery!! 1、 kubeconfig /root/.kube/config, User ‘kubernetes-admin’ Cluster: S…

SpringCloud(一) 服务架构的演变及注册RestTemplate实现服务的远程调用

目录 一, 服务架构的演变 1.1 单体架构 1.2 分布式架构 1.3 微服务 1.4 SpringCloud 二, 服务拆分和远程调用 2,1 服务拆分原则 2.2 服务拆分示例 2.3 创建相应数据库 2.4 实现远程调用示例 1, 更改需求 2, 注册RestTemplate实现远程调用 2.5 服务消费者和提供者 一…

【数据分析】上市公司半年报数据分析

前言 前文介绍过使用网络技术获取上市公司半年报数据的方法&#xff0c;本文将对获取到的数据进行简要的数据分析。 获取数据的代码介绍在下面的两篇文章中 【java爬虫】使用selenium获取某交易所公司半年报数据-CSDN博客 【java爬虫】公司半年报数据展示-CSDN博客 全量数…

Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(中)

Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物Dash&#xff08;中&#xff09; 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://…

微服务框架Consul--新手入门

Consul Consul 是由 HashiCorp 开发的一款软件工具&#xff0c;提供了一组功能&#xff0c;用于服务发现、配置管理和网络基础设施自动化。它旨在帮助组织管理现代分布式和微服务架构系统的复杂性。以下是Consul的一些关键方面和功能&#xff1a; 服务发现&#xff1a;Consul …

【Linux】centOS7安装配置及Linux的常用命令---超详细

一&#xff0c;centOS 1.1 centOS的概念 CentOS&#xff08;Community Enterprise Operating System&#xff09;是一个由社区支持的企业级操作系统&#xff0c;它是以Red Hat Enterprise Linux&#xff08;RHEL&#xff09;源代码为基础构建的。CentOS提供了一个稳定、可靠且…

软件测试面试高频30道面试题

如果哪个测试经理在看我的文章&#xff0c;希望对面试者要微笑&#xff0c;不然面试结束&#xff0c;出门之后就一万个草泥马奔腾而过&#xff0c;其实面试者并不是希望你给他们什么&#xff0c;而是一种尊重&#xff0c;平等的谈话&#xff0c;不要高高在上感觉自己超牛逼一样…

论文范文:论基于架构的软件设计方法及应用

注意:范文只适用于帮助大家打开写作思路,并不能作为素材直接用于平时练习、考试中。考试中直接使用范文的素材,会有被认定为雷同卷的风险。 摘要: 2022年4月,本人所在单位计划研发生态集装箱管理控制平台项目。该平台主要用于与现有公司生态集装箱产品做对接,达到远程控制…

七层负载均衡 HAproxy

一、HAproxy 1、负载均衡类型&#xff1a; (1) 无负载均衡&#xff1a; 没有负载均衡&#xff0c;用户直接连接到 Web 服务器。当许多用户同时访问服务器时&#xff0c;可能无法连接。 (2) 四层负载均衡&#xff1a; 用户访问负载均衡器&#xff0c;负载均衡器将用户的请求…