SpringBoot处理全局异常详解(全面详细+Gitee源码)

news/2024/11/15 20:35:00/

前言:在日常的开发工作中,项目在运行过程中多多少少是避免不了报错的,对于报错信息肯定不可以把全部信息都抛给客户端去显示,这里就需要我们对常见的七种异常情况统一进行处理,让整个项目更加优雅。

目录

一、基本介绍

二、项目整体结构图

三、基础配置 

1、导入pom.xml依赖

2、application.yml配置

四、常用类封装

1、HttpStatus状态码常量类

2、AjaxResult统一封装返回的结果类

3、ServiceException业务异常类封装

4、User实体类

五、数据库查询

1、UserMapper.xml文件

2、Mapper接口

六、ExceptionAdvice核心全局拦截配置类

七、异常测试

1、权限校验异常

2、请求方式异常

3、参数校验异常

4、数据库异常(非常重要)

5、运行异常

6、业务异常

7、全局异常

八、Gitee源码 


一、基本介绍

这次博客的主角就是@RestControllerAdvice这个注解,这个一个组合注解由@ControllerAdvice和@ResponseBody组成,@RestControllerAdvice会帮助我们把信息转成json格式返回。

在全局异常处理类只需要在类上标注@RestControllerAdvice,并在处理相应异常的方法上使用@ExceptionHandler注解,写明处理哪个异常即可。

注:异常的拦截有顺序,子类异常会优先匹配子类异常处理器。

废话不多说,本博客列举了实际开发中常见的七种异常进行配置,直接上代码!

二、项目整体结构图

这是项目最后的运行的整个结构

三、基础配置 

1、导入pom.xml依赖

项目中引入的依赖包都贴出来了,一共这么多复制即可。

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 常用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><!-- 参数验证依赖 --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>6.1.5.Final</version></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>8.0.26</version></dependency><!--Mybatis依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

2、application.yml配置

server:port: 8080spring:datasource:username: 账号password: 密码url: jdbc:mysql://地址:3306/数据库?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCdriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapping/*.xml

四、常用类封装

1、HttpStatus状态码常量类

这边定义了目前常见的响应的状态码,直接拷贝即可。

package com.example.exception.constant;/*** 返回状态码* @author HTT*/
public class HttpStatus
{/*** 操作成功*/public static final int SUCCESS = 200;/*** 对象创建成功*/public static final int CREATED = 201;/*** 请求已经被接受*/public static final int ACCEPTED = 202;/*** 操作已经执行成功,但是没有返回数据*/public static final int NO_CONTENT = 204;/*** 资源已被移除*/public static final int MOVED_PERM = 301;/*** 重定向*/public static final int SEE_OTHER = 303;/*** 资源没有被修改*/public static final int NOT_MODIFIED = 304;/*** 参数列表错误(缺少,格式不匹配)*/public static final int BAD_REQUEST = 400;/*** 未授权*/public static final int UNAUTHORIZED = 401;/*** 访问受限,授权过期*/public static final int FORBIDDEN = 403;/*** 资源,服务未找到*/public static final int NOT_FOUND = 404;/*** 不允许的http方法*/public static final int BAD_METHOD = 405;/*** 资源冲突,或者资源被锁*/public static final int CONFLICT = 409;/*** 不支持的数据,媒体类型*/public static final int UNSUPPORTED_TYPE = 415;/*** 系统内部错误*/public static final int ERROR = 500;/*** 接口未实现*/public static final int NOT_IMPLEMENTED = 501;
}

2、AjaxResult统一封装返回的结果类

package com.example.exception.domain;import com.example.exception.constant.HttpStatus;
import org.apache.commons.lang3.ObjectUtils;import java.util.HashMap;/*** 操作消息提醒* * @author HTT*/
public class AjaxResult extends HashMap<String, Object>
{private static final long serialVersionUID = 1L;/** 状态码 */public static final String CODE_TAG = "code";/** 返回内容 */public static final String MSG_TAG = "msg";/** 数据对象 */public static final String DATA_TAG = "data";/*** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。*/public AjaxResult(){}/*** 初始化一个新创建的 AjaxResult 对象* * @param code 状态码* @param msg 返回内容*/public AjaxResult(int code, String msg){super.put(CODE_TAG, code);super.put(MSG_TAG, msg);}/*** 初始化一个新创建的 AjaxResult 对象* * @param code 状态码* @param msg 返回内容* @param data 数据对象*/public AjaxResult(int code, String msg, Object data){super.put(CODE_TAG, code);super.put(MSG_TAG, msg);if (ObjectUtils.isNotEmpty(data)){super.put(DATA_TAG, data);}}/*** 返回成功消息* * @return 成功消息*/public static AjaxResult success(){return AjaxResult.success("操作成功");}/*** 返回成功数据* * @return 成功消息*/public static AjaxResult success(Object data){return AjaxResult.success("操作成功", data);}/*** 返回成功消息* * @param msg 返回内容* @return 成功消息*/public static AjaxResult success(String msg){return AjaxResult.success(msg, null);}/*** 返回成功消息* * @param msg 返回内容* @param data 数据对象* @return 成功消息*/public static AjaxResult success(String msg, Object data){return new AjaxResult(HttpStatus.SUCCESS, msg, data);}/*** 返回错误消息* * @return*/public static AjaxResult error(){return AjaxResult.error("操作失败");}/*** 返回错误消息* * @param msg 返回内容* @return 警告消息*/public static AjaxResult error(String msg){return AjaxResult.error(msg, null);}/*** 返回错误消息* * @param msg 返回内容* @param data 数据对象* @return 警告消息*/public static AjaxResult error(String msg, Object data){return new AjaxResult(HttpStatus.ERROR, msg, data);}/*** 返回错误消息* * @param code 状态码* @param msg 返回内容* @return 警告消息*/public static AjaxResult error(int code, String msg){return new AjaxResult(code, msg, null);}/*** 方便链式调用** @param key 键* @param value 值* @return 数据对象*/@Overridepublic AjaxResult put(String key, Object value){super.put(key, value);return this;}
}

3、ServiceException业务异常类封装

package com.example.exception.exception;/*** 业务异常类封装* @author HTT*/
public final class ServiceException extends RuntimeException
{private static final long serialVersionUID = 1L;/*** 错误码*/private Integer code;/*** 错误提示*/private String message;/*** 错误明细,内部调试错误*/private String detailMessage;/*** 空构造方法,避免反序列化问题*/public ServiceException(){}public ServiceException(String message){this.message = message;}public ServiceException(String message, Integer code){this.message = message;this.code = code;}public String getDetailMessage(){return detailMessage;}@Overridepublic String getMessage(){return message;}public Integer getCode(){return code;}public ServiceException setMessage(String message){this.message = message;return this;}public ServiceException setDetailMessage(String detailMessage){this.detailMessage = detailMessage;return this;}
}

4、User实体类

package com.example.exception.domain;import lombok.Data;import javax.validation.constraints.NotBlank;@Data
public class User {@NotBlank(message = "用户名不能为空")private String username;@NotBlank(message = "密码不能为空")private String password;
}

五、数据库查询

1、UserMapper.xml文件

这边我故意查询的是我数据库中目前不存在的表none_txt

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.exception.mapper.UserMapper"><select id="select" resultType="Integer">SELECT * FROM none_txt</select>
</mapper>

2、Mapper接口

package com.example.exception.mapper;import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper {public void select();
}

六、ExceptionAdvice核心全局拦截配置类

这边我一共列举了实际项目开发当中常见的七种异常情况:

1、权限校验异常

    @ExceptionHandler(AccessDeniedException.class)public AjaxResult handleAccessDeniedException(AccessDeniedException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址{},权限校验失败{}", requestURI, e.getMessage());return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");}

2、请求方式不支持

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址{},不支持{}请求", requestURI, e.getMethod());return AjaxResult.error(e.getMessage());}

3、参数验证失败异常

    public AjaxResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e,HttpServletRequest request) {String requestURI = request.getRequestURI();String message = e.getBindingResult().getFieldError().getDefaultMessage();log.error("请求地址{},参数验证失败{}", requestURI, e.getObjectName(),e);return AjaxResult.error(message);}

4、数据库异常

错误SQL语句异常

    @ExceptionHandler(BadSqlGrammarException.class)public AjaxResult handleBadSqlGrammarException(BadSqlGrammarException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生数据库异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}

拦截表示违反数据库的完整性约束导致的异常

    @ExceptionHandler(DataIntegrityViolationException.class)public AjaxResult handleDataIntegrityViolationException(DataIntegrityViolationException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生数据库异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}

拦截违反数据库的非完整性约束导致的异常,可能也会拦截一些也包括 SQL 语句错误、连接问题、权限问题等各种数据库异常。 

    @ExceptionHandler(UncategorizedSQLException.class)public AjaxResult handleUncategorizedSqlException(UncategorizedSQLException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生数据库异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}

5、拦截未知的运行时异常

    @ExceptionHandler(RuntimeException.class)public AjaxResult handleRuntimeException(RuntimeException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址{},发生未知运行异常", requestURI, e);return AjaxResult.error(e.getMessage());}

6、业务自定义异常

    @ExceptionHandler(ServiceException.class)public AjaxResult handleServiceException(ServiceException e,HttpServletRequest request) {String requestURI = request.getRequestURI();Integer code = e.getCode();log.error("请求地址{},发生业务自定义异常{}",requestURI,e.getMessage(), e);return code != null ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());}

7、全局异常

    @ExceptionHandler(Exception.class)public AjaxResult handleException(Exception e,HttpServletRequest request){String requestURI = request.getRequestURI();log.error("请求地址{},发生系统异常",requestURI,e);return AjaxResult.error(e.getMessage());}

完整代码: 

package com.example.exception.exception;import com.example.exception.constant.HttpStatus;
import com.example.exception.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;/*** @author HTT*/
@RestControllerAdvice
@Slf4j
public class ExceptionAdvice {/*** 权限校验异常* @param e* @param request* @return*/@ExceptionHandler(AccessDeniedException.class)public AjaxResult handleAccessDeniedException(AccessDeniedException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址{},权限校验失败{}", requestURI, e.getMessage());return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");}/*** 请求方式不支持* @param e* @param request* @return*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址{},不支持{}请求", requestURI, e.getMethod());return AjaxResult.error(e.getMessage());}/*** 参数验证失败异常* @param e* @param request* @return*/@ExceptionHandler(MethodArgumentNotValidException.class)public AjaxResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e,HttpServletRequest request) {String requestURI = request.getRequestURI();String message = e.getBindingResult().getFieldError().getDefaultMessage();log.error("请求地址{},参数验证失败{}", requestURI, e.getObjectName(),e);return AjaxResult.error(message);}/*** 拦截错误SQL异常* @param e* @param request* @return*/@ExceptionHandler(BadSqlGrammarException.class)public AjaxResult handleBadSqlGrammarException(BadSqlGrammarException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生数据库异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}/*** 可以拦截表示违反数据库的完整性约束导致的异常。* @param e* @param request* @return*/@ExceptionHandler(DataIntegrityViolationException.class)public AjaxResult handleDataIntegrityViolationException(DataIntegrityViolationException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生数据库异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}/*** 可以拦截违反数据库的非完整性约束导致的异常,可能也会拦截一些也包括 SQL 语句错误、连接问题、权限问题等各种数据库异常。* @param e* @param request* @return*/@ExceptionHandler(UncategorizedSQLException.class)public AjaxResult handleUncategorizedSqlException(UncategorizedSQLException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生数据库异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}/*** 拦截未知的运行时异常* @param e* @param request* @return*/@ExceptionHandler(RuntimeException.class)public AjaxResult handleRuntimeException(RuntimeException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址{},发生未知运行异常", requestURI, e);return AjaxResult.error(e.getMessage());}/*** 业务自定义异常* @param e* @param request* @return*/@ExceptionHandler(ServiceException.class)public AjaxResult handleServiceException(ServiceException e,HttpServletRequest request) {String requestURI = request.getRequestURI();Integer code = e.getCode();log.error("请求地址{},发生业务自定义异常{}",requestURI,e.getMessage(), e);return code != null ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());}/*** 全局异常* @param e* @param request* @return*/@ExceptionHandler(Exception.class)public AjaxResult handleException(Exception e,HttpServletRequest request){String requestURI = request.getRequestURI();log.error("请求地址{},发生系统异常",requestURI,e);return AjaxResult.error(e.getMessage());}}

七、异常测试

这边我们逐一对每一个异常进行拦截测试。

1、权限校验异常

测试运行代码:

    /*** 权限测试*/@GetMapping("/auth")public void auth() throws AccessDeniedException {throw new AccessDeniedException("暂无权限");}

浏览器输入:http://localhost:8080/user/auth

浏览器显示如下:

 后台日志显示如下:

2、请求方式异常

测试运行代码:

    /*** 请求不支持异常测试*/@PostMapping("/request")public void request() {System.out.println("request");}

浏览器输入:http://localhost:8080/user/request

浏览器显示如下: 

后台日志显示如下:

3、参数校验异常

测试运行代码:

    /*** 参数验证异常测试* @param user*/@PostMapping("/valid")public void Valid(@Valid @RequestBody User user){System.out.println(user.toString());}

使用postman测试:

后台日志显示如下:

4、数据库异常(非常重要)

这边我们就拿BadSqlGrammarException这个异常进行举例,如果表、字段或者视图等情况不存在会抛出BadSqlGrammarException异常,而这个异常是继承RuntimeException异常的,进行了特殊处理,不然会把SQL语句也暴漏给客户端显示。

测试代码如下:

    @Resourceprivate UserMapper userMapper;/*** 数据库异常*/@GetMapping("/badSqlGrammarException")public void badSqlGrammarException() throws Exception {userMapper.select();}

如果把这段代码注释掉:

    /*** 拦截错误SQL异常* @param e* @param request* @return*/@ExceptionHandler(BadSqlGrammarException.class)public AjaxResult handleBadSqlGrammarException(BadSqlGrammarException e, HttpServletRequest request){String requestURI = request.getRequestURI();log.error("请求地址'{}',发生SQL异常.", requestURI, e);return AjaxResult.error(HttpStatus.ERROR, "数据库异常!");}

浏览器输入:http://localhost:8080/user/badSqlGrammarException

浏览器显示如下:

显而易见,当我们注释掉了这段自定义的异常以后,返回给前端的错误信息中居然还包含了我们的SQL执行语句,这显然是不合理的,应该是浏览器端只能提示一个例如数据库异常的通用提示,具体信息在我们的后台进行记录。 

所以当我们加上那段自定义异常,再执行一遍看效果:

后台日志显示如下:

注意:这个异常属于BadSqlGrammarException,它是SpringFramework定义的异常,而SQLException属于Java SQL标准定义的异常。如果要被异常拦截器拦截的话,定义的异常应该是BadSqlGrammarException.class进行捕获。

BadSqlGrammarException和SQLException属于并列的异常,BadSqlGrammarException并未继承SQLException。但它们都属于同一个父类RuntimeException

另外还有2个可能会发生的异常

1、DataIntegrityViolationException:可以拦截表示违反数据库的完整性约束导致的异常。

2、UncategorizedSQLException:可以拦截违反数据库的非完整性约束导致的异常,可能也会拦截一些也包括 SQL 语句错误、连接问题、权限问题等各种数据库异常。

完整性约束:

1、主键约束:唯一标识表中每条记录的约束。

2、非空约束:要求字段的值不能为空的约束。

3、唯一约束:要求字段的值在表中唯一的约束。

4、外键约束:要求字段的值必须是另一个表的主键约束的值的约束。

非完整性约束:

1、数据类型约束:对字段的数据类型、长度、格式等做出的限制。

如字段长度限制、数字位数限制、日期格式限制等。

2、默认值约束:对字段的默认值做出的规定。

如字段的默认值,如果插入数据时未指定该字段的值,则使用默认值。

3、检查约束:对字段的值做更加灵活的约束。

如值的范围、值之间的关系等,属于逻辑约束。

总结来说:非完整性约束主要包括数据类型约束、默认值约束和检查约束。它们分别定义了字段的数据类型、默认值以及更为复杂的逻辑限制。而完整性约束则涉及实体完整性,如主键、非空、唯一以及外键约束。

5、运行异常

测试运行代码:

    /*** 运行异常*/@GetMapping("/runtimeException")public void runtimeException(){throw new RuntimeException();}

浏览器输入:http://localhost:8080/user/request

浏览器显示如下: 

后台日志显示如下:

6、业务异常

测试运行代码:

    /*** 业务自定义异常*/@GetMapping("/serviceException")public void serviceException() {throw new ServiceException("业务异常!");}

浏览器输入:http://localhost:8080/user/request

浏览器显示如下: 

后台日志显示如下:

7、全局异常

测试运行代码:

    /*** 全局异常*/@GetMapping("/exception")public void exception() throws Exception {throw new Exception("全局异常!");}

浏览器输入:http://localhost:8080/user/exception

浏览器显示如下: 

 后台日志显示如下:

八、Gitee源码 

SpringBoot处理实际开发中常见的七种全局异常详解: 在日常的开发工作中,项目在运行过程中多多少少是避免不了报错的,对于报错信息肯定不可以把全部信息都抛给客户端去显示,这里就需要我们对常见的七种异常情况统一进行处理,让整个项目更加优雅。


http://www.ppmy.cn/news/724946.html

相关文章

中国移动发狠,给携转用户巨额优惠,反击中国电信

近日据业内人士指出中国移动针对携号转网用户提供了巨额优惠&#xff0c;只要21元就可获得30GB全国通用流量移动套餐&#xff0c;再另送500M宽带&#xff0c;两年免费、安装费全免&#xff0c;对于我们老用户来说这可是139元套餐才能享受到&#xff0c;这显示出中国移动为了争夺…

Java实现PDF转Word【收集整理】

首先感谢 Mgg9702 博主提供的转换依赖包处理&#xff0c;关于如何获得一个破解的pdf转word我这里就不追述了&#xff0c;有需要去看&#xff1a; https://blog.csdn.net/Mgg9702/article/details/124987483?spm1001.2014.3001.5506 我这里主要涉及到整理一个pdf转word的jar工…

以太网 (数据链路层协议)

以太网 认识以太网以太网数据帧 认识以太网 “以太网” 不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含了数据链路层的内容&#xff0c;也包含了一些物理层的内容。 例如&#xff1a;规定了网络拓扑结构&#xff0c;访问控制方式&#xff0c;传输速率等&a…

重装系统会影响到电脑的正常使用吗

​重装系统对电脑有影响吗?重装系统是指对计算机的操作系统进行重新的安装。当用户错误操作或遭受病毒的破坏时&#xff0c;系统中的重要文件就会受损导致错误&#xff0c;严重甚至可能出现崩溃&#xff0c;电脑无法启动操作&#xff0c;因此不得不进行重新安装。一些喜欢操作…

xp系统安装c语言教程,神舟战神K670C-G4A1笔记本u盘重装系统xp教程

神舟战神K670C-G4A1笔记本预装Windows 10系统&#xff0c;搭载了Intel Pentium G5420处理器&#xff0c;主频为3.8GHz&#xff0c;而三级缓存为L3 4M。另外&#xff0c;电脑还配置了8GB运行内存&#xff0c;而最大支持内存则是32GB&#xff0c;整体性价比较高。但是&#xff0c…

关于神舟电脑U盘重装windows10系统

关于神舟电脑U盘重装windows10系统 神舟电脑重装新安装系统遇到的坑&#xff0c;之前电脑安装使用的是Linux系统&#xff0c;但是由于电脑版本原因导致安装Linux失败&#xff0c;于是便想装回windows10系统&#xff0c;本人从售后获取windows10专业版镜像以后使用ultralso&…

0基础学习VR全景平台篇 第55篇:专业版功能-数据统计

使用蛙色VR平台数据统计功能&#xff0c;可以统计分析整个账号下【所有作品】的访问数据&#xff1b; 亦可分析单个作品中【每个场景】的访问数据。 账号数据统计功能位置 单作品数据统计功能位置 一、本功能将用在哪里&#xff1f; 数据统计功能&#xff0c;可实现对作品总访…

matlab语言的前世今生

matlab语言的算法库是用什么语言实现的&#xff1f; Matlab的算法库是用C和C语言实现的。 Matlab本身是一个解释型的高级编程语言&#xff0c;但它的核心算法库是使用更底层的C和C语言编写的。这些库提供了许多数值计算、统计分析、信号处理、图像处理、优化等常用算法函数&…