news 2026/2/7 15:51:13

javaSE,对于异常层面的认识

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
javaSE,对于异常层面的认识

我们知道,代码是运行在jvm里面的。但是要让接口能顺利运行下去,不会因为报错,而中断,或者报错了有给前端返回对应的问题。

我们来认识一下,java的异常体系,以及如何处理异常

1.java中有哪些类型的异常

2.如何处理这些异常

3.自定义处理异常,有哪些异常可以抓取

4.在实接口处理中,对异常处理有哪些原则。

5.使用springmvc的全局异常捕获,设计异常捕获,对接口返回,的设计思路和流程是什么

一、Java异常体系

1. 异常分类层次结构

Throwable (所有异常/错误的父类) ├── Error (系统级错误,一般程序无法处理) │ ├── VirtualMachineError │ ├── OutOfMemoryError │ └── StackOverflowError └── Exception (程序可处理的异常) ├── RuntimeException (运行时异常,非受检异常) │ ├── NullPointerException │ ├── IndexOutOfBoundsException │ ├── IllegalArgumentException │ └── ... └── CheckedException (受检异常,编译时检查) ├── IOException ├── SQLException ├── ClassNotFoundException └── ...

2. 主要异常类型说明

RuntimeException(运行时异常/非受检异常)

  • 代码逻辑问题导致,不强制捕获
  • 常见子类:
    • NullPointerException:空指针
    • IllegalArgumentException:非法参数
    • IndexOutOfBoundsException:下标越界
    • ClassCastException:类型转换错误

CheckedException(受检异常)

  • 编译时强制检查,必须处理(try-catch或throws)
  • 常见子类:
    • IOException:I/O操作异常
    • SQLException:数据库操作异常
    • ParseException:解析异常

Error(错误)

  • JVM或系统严重问题,一般不需要捕获处理

二、异常处理方式

1. 基本处理机制

try{// 可能抛出异常的代码}catch(SpecificExceptione){// 处理特定异常}catch(Exceptione){// 处理其他异常}finally{// 无论是否异常都会执行(资源清理)}

2. try-with-resources(Java 7+)

try(FileInputStreamfis=newFileInputStream("file.txt");BufferedReaderbr=newBufferedReader(newInputStreamReader(fis))){// 自动关闭资源}catch(IOExceptione){// 异常处理}

3. throws声明

publicvoidreadFile()throwsIOException{// 方法内部不处理,由调用者处理}

三、自定义异常处理

1. 自定义异常类

// 业务异常基类publicclassBusinessExceptionextendsRuntimeException{privateStringcode;privateStringmessage;publicBusinessException(Stringcode,Stringmessage){super(message);this.code=code;this.message=message;}}// 具体业务异常publicclassUserNotFoundExceptionextendsBusinessException{publicUserNotFoundException(){super("USER_NOT_FOUND","用户不存在");}}

2. 可捕获的异常类型

@ControllerAdvicepublicclassGlobalExceptionHandler{// 1. 处理自定义业务异常@ExceptionHandler(BusinessException.class)// 2. 处理运行时异常@ExceptionHandler(RuntimeException.class)// 3. 处理受检异常@ExceptionHandler(IOException.class)@ExceptionHandler(SQLException.class)// 4. 处理参数验证异常@ExceptionHandler(MethodArgumentNotValidException.class)// 5. 处理未捕获的异常@ExceptionHandler(Exception.class)}

四、接口异常处理原则

1.尽早抛出,晚点捕获

  • 在能检测到问题时立即抛出异常
  • 在合适的层次(通常是Controller层)统一处理

2.异常信息明确

// 不推荐thrownewException("操作失败");// 推荐thrownewBusinessException("ORDER_PAID_FAILED","订单支付失败,用户余额不足,订单号:"+orderNo);

3.区分业务异常和系统异常

  • 业务异常:用户操作不当、数据校验失败等,应该给用户友好提示
  • 系统异常:数据库连接失败、网络超时等,记录日志,给用户通用错误提示

4.异常日志记录

@ExceptionHandler(Exception.class)publicResponseEntity<Result>handleException(Exceptione,HttpServletRequestrequest){log.error("请求URI: {}, 异常类型: {}, 异常信息: {}",request.getRequestURI(),e.getClass().getName(),e.getMessage(),e);// 记录完整堆栈// ...}

5.不要吞掉异常

// 错误做法try{// ...}catch(Exceptione){// 什么都没做,异常被吞掉}// 正确做法try{// ...}catch(Exceptione){log.error("操作失败",e);thrownewBusinessException("OPERATION_FAILED","操作失败");}

五、Spring MVC全局异常捕获设计

1. 统一返回结构

@Data@NoArgsConstructor@AllArgsConstructorpublicclassResult<T>{privatebooleansuccess;privateStringcode;privateStringmessage;privateTdata;privateLongtimestamp;publicstatic<T>Result<T>success(Tdata){returnnewResult<>(true,"SUCCESS","操作成功",data,System.currentTimeMillis());}publicstatic<T>Result<T>error(Stringcode,Stringmessage){returnnewResult<>(false,code,message,null,System.currentTimeMillis());}}

2. 全局异常处理器

@Slf4j@RestControllerAdvicepublicclassGlobalExceptionHandler{/** * 处理业务异常 */@ExceptionHandler(BusinessException.class)publicResponseEntity<Result<Void>>handleBusinessException(BusinessExceptione,HttpServletRequestrequest){log.warn("业务异常 - URI: {}, Code: {}, Message: {}",request.getRequestURI(),e.getCode(),e.getMessage());returnResponseEntity.ok().body(Result.error(e.getCode(),e.getMessage()));}/** * 处理参数校验异常 */@ExceptionHandler(MethodArgumentNotValidException.class)publicResponseEntity<Result<Map<String,String>>>handleValidationException(MethodArgumentNotValidExceptione){Map<String,String>errors=newHashMap<>();e.getBindingResult().getFieldErrors().forEach(error->errors.put(error.getField(),error.getDefaultMessage()));returnResponseEntity.ok().body(Result.error("VALIDATION_FAILED","参数校验失败").data(errors));}/** * 处理系统异常 */@ExceptionHandler(Exception.class)publicResponseEntity<Result<Void>>handleSystemException(Exceptione,HttpServletRequestrequest){log.error("系统异常 - URI: {}, Exception: {}",request.getRequestURI(),e.getMessage(),e);// 生产环境返回通用错误信息,避免暴露系统细节Stringmessage="系统内部错误,请联系管理员";if("dev".equals(env)){message=e.getMessage();}returnResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Result.error("SYSTEM_ERROR",message));}}

3. 业务层异常使用

@ServicepublicclassUserService{publicUsergetUserById(LonguserId){returnuserRepository.findById(userId).orElseThrow(()->newUserNotFoundException());}publicvoidcreateUser(UserCreateRequestrequest){// 参数校验if(StringUtils.isBlank(request.getUsername())){thrownewBusinessException("USERNAME_EMPTY","用户名不能为空");}// 业务逻辑校验if(userRepository.existsByUsername(request.getUsername())){thrownewBusinessException("USERNAME_EXISTS","用户名已存在");}// 业务操作try{Useruser=newUser();BeanUtils.copyProperties(request,user);userRepository.save(user);}catch(DataIntegrityViolationExceptione){thrownewBusinessException("DATA_INTEGRITY_ERROR","数据完整性错误");}}}

4. 异常处理流程设计

客户端请求 ↓ Controller层接收请求 ↓ 参数验证(@Valid) → 失败 → 抛出MethodArgumentNotValidException ↓ Service层业务处理 → 业务异常 → 抛出BusinessException → 系统异常 → 抛出RuntimeException/SQLException等 ↓ Controller层返回正常结果 ↓ 异常发生 → 被@ExceptionHandler捕获 ↓ 全局异常处理器根据异常类型处理 ↓ 统一封装为Result对象 ↓ 返回给客户端

5. 最佳实践建议

  1. 异常分类处理

    • HTTP 400:客户端参数错误
    • HTTP 401/403:认证授权错误
    • HTTP 404:资源不存在
    • HTTP 500:服务器内部错误
  2. 异常信息国际化

@ExceptionHandler(BusinessException.class)publicResponseEntity<Result<Void>>handleBusinessException(BusinessExceptione,Localelocale){Stringmessage=messageSource.getMessage("error."+e.getCode(),null,e.getMessage(),locale);returnResponseEntity.ok(Result.error(e.getCode(),message));}
  1. 监控告警
    • 对系统异常进行监控
    • 设置阈值告警
    • 关键业务异常记录到专门日志

通过这样的设计,可以确保:
4. 接口异常不会中断服务流程
5. 前端获得友好的错误提示
6. 后端能够完整记录异常信息
7. 系统具备良好的可维护性和可观测性

特别在实际开发接口中使用这异常要注意的点:
明确异常类型:不直接用 catch (Exception e) 一把抓,而是根据可能抛出的具体异常类型来捕获,比如 IOException、SQLException。

日志一定要打:在 catch 里至少要把异常堆栈信息打印到日志里,用 log.error(“出错了”, e),不然线上出问题没法排查。

不要吞掉异常:最忌讳 catch 里什么都不写,或者只打印 e.getMessage()(这没堆栈信息),这叫“吞异常”,会坑死人。

能处理的处理,不能处理的抛:如果是业务上能处理的(比如用户输入格式不对),就给用户友好提示;如果是系统级错误(比如数据库连不上),要么抛出去让上层统一处理,要么降级返回默认值。

资源要释放:用 try-with-resources(JDK7+)自动关流,比手动在 finally 里关更安全简洁。”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 10:05:28

关于spring的全量认识

这里聚焦一个问题&#xff0c;到底对spring产生怎么样的认识&#xff0c;才算有个稍微全面的认识。 本文章不适合初学者看。适合想集大成者看。 1.工程引入与配置层面&#xff1a; 什么版本的spring 2.代码层实际应用层面&#xff1a; spring提供了哪些机制。供我们使用 1.ioc …

作者头像 李华
网站建设 2026/2/2 8:48:00

B站视频内容提取神器:5秒读懂长视频的AI革命

B站视频内容提取神器&#xff1a;5秒读懂长视频的AI革命 【免费下载链接】BilibiliSummary A chrome extension helps you summary video on bilibili. 项目地址: https://gitcode.com/gh_mirrors/bi/BilibiliSummary 你是否曾经面对B站上几十分钟的教程视频&#xff0c…

作者头像 李华
网站建设 2026/2/6 2:17:25

OpCore-Simplify终极指南:一键实现专业级Hackintosh自动化配置

OpCore-Simplify终极指南&#xff1a;一键实现专业级Hackintosh自动化配置 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 对于想要体验macOS系统但面…

作者头像 李华
网站建设 2026/2/3 15:08:19

OpenCore智能助手:新手也能轻松搭建黑苹果系统

OpenCore智能助手&#xff1a;新手也能轻松搭建黑苹果系统 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify OpenCore智能助手是一款革命性的黑苹果系统…

作者头像 李华
网站建设 2026/2/5 17:46:27

OpCore Simplify:告别繁琐配置,3分钟搞定黑苹果EFI

OpCore Simplify&#xff1a;告别繁琐配置&#xff0c;3分钟搞定黑苹果EFI 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的OpenCore配置发…

作者头像 李华
网站建设 2026/1/29 11:20:03

Realtek RTL8125 2.5GbE网卡驱动完整安装手册

Realtek RTL8125 2.5GbE网卡驱动完整安装手册 【免费下载链接】realtek-r8125-dkms A DKMS package for easy use of Realtek r8125 driver, which supports 2.5 GbE. 项目地址: https://gitcode.com/gh_mirrors/re/realtek-r8125-dkms 还在为Linux系统无法识别高速网络…

作者头像 李华