Guava处理异常

guava由Google开发,它提供了大量的核心Java库,例如:集合、缓存、原生类型支持、并发库、通用注解、字符串处理和I/O操作等。

异常处理

传统的Java异常处理通常包括try-catch-finally块和throws关键字。

遇到FileNotFoundException或IOException

try {// 读取文件的操作
} catch (FileNotFoundException e) {// 处理文件未找到的情况
} catch (IOException e) {// 处理读取文件时的IO异常
} finally {// 最后,不管有没有异常,都要执行的代码,比如关闭文件流
}

有时候一个方法里面可能需要捕获多种异常,这就导致了代码的复杂度急剧上升。很多时候咱们还需要把捕获到的异常转换成另一种异常再抛出,这就需要咱们手动处理异常的传播,代码就更加复杂了

而Guava的Throwables类,就是为了解决这些问题而生的。它提供了一系列静态方法,帮助咱们简化异常的处理和传播。比如,咱们可以用Throwables.propagate来把检查异常转换为运行时异常,或者用Throwables.getStackTraceAsString获取异常的堆栈字符串,这些都是在传统Java异常处理中比较难实现的。

public void doSomethingRisky() {try {// 一些可能抛出检查型异常的代码} catch (IOException e) {// 使用Throwables.propagate将检查型异常转换为未检查型异常throw Throwables.propagate(e);}
}

这样做的好处:不需要在方法签名中声明所有可能的异常,简化了代码。但同时,它也保留了原始异常信息,便于调试和错误追踪。
在这里插入图片描述
另一个超级有用的功能是Throwables.getStackTraceAsString(Throwable)。有时候,咱们需要将异常的堆栈信息记录到日志中,或者发送到某个监控系统。这个方法可以直接把异常的堆栈信息转换为字符串,方便咱们处理:

try {// 可能抛出异常的代码
} catch (Exception e) {// 获取异常的堆栈信息字符串String stackTrace = Throwables.getStackTraceAsString(e);// 做些什么,比如记录日志
}

在这里插入图片描述
此外,Throwables.getRootCause(Throwable) 也很实用。有时候异常会被包装多层,最原始的异常信息可能隐藏在几层包装之下。这个方法可以帮咱们直接找到最底层的异常原因,方便定位问题:

try {// 一些可能抛出包装过的异常的操作
} catch (Exception e) {// 直接找到根本原因Throwable rootCause = Throwables.getRootCause(e);// 处理或记录根本原因
}

通过这些方法,Throwables类帮咱们简化了异常的处理过程,让异常信息更加清晰,调试更加方便。

实际应用:

案例一:

读取文件内容的方法,在传统的Java处理方式中,你可能会遇到FileNotFoundException和IOException

public String readFile(String path) throws IOException {try {// 读取文件的操作return ...;} catch (FileNotFoundException e) {// 处理文件未找到的情况} catch (IOException e) {// 处理读取文件时的IO异常} finally {// 关闭资源}
}

但是,使用Guava的Throwables

public String readFile(String path) {try {// 读取文件的操作return ...;} catch (Exception e) {Throwables.throwIfInstanceOf(e, IOException.class);throw Throwables.propagate(e);} finally {// 关闭资源}
}

在这个例子中,throwIfInstanceOf方法会检查捕获的异常是否是指定类型的实例。如果是,就抛出异常;如果不是,就用propagate方法将它转换为运行时异常。这样做的好处是减少了代码量,同时保留了异常处理的清晰性和准确性。

案例二:

处理数据库操作时遇到了异常,这个异常可能被多层包装。传统的做法可能需要逐层检查

用Guava可以简化这一过程

try {// 一些数据库操作,可能会抛出SQLException
} catch (Exception e) {Throwable rootCause = Throwables.getRootCause(e);//getRootCause方法快速定位到最底层的异常原因,这对于调试和异常处理来说非常有用if (rootCause instanceof SQLException) {// 处理SQL异常}
}

案例三:

把异常信息记录到日志中。

try {// 可能会出现异常的操作
} catch (Exception e) {logger.error("An error occurred: " + e.getMessage(), e);
}

但是,有时候仅仅记录异常信息还不够,咱们还需要异常的完整堆栈跟踪。

//能在日志中获得完整的异常堆栈信息,对于后期的问题分析和修复大有帮助。
try {// 可能会出现异常的操作
} catch (Exception e) {logger.error("An error occurred: " + Throwables.getStackTraceAsString(e));
}

最佳异常日志记录,当捕获到异常时,除了记录异常消息,咱们还可以记录整个异常堆栈:
即使异常被捕获并处理,咱们也能在日志中得到足够的信息来分析问题。

try {// 可能抛出异常的操作
} catch (Exception e) {logger.error("Exception occurred: " + e.toString());logger.error("Stack trace: " + Throwables.getStackTraceAsString(e));
}

案例四:

链式异常处理

/**throwIfInstanceOf方法按顺序检查异常类型。如果异常匹配,则抛出相应的异常,否则最后通过propagate转换为运行时异常。这种方法使得异常处理变得既简洁又清晰。
*/
try {// 一些可能抛出多种异常的文件操作
} catch (Exception e) {Throwables.throwIfInstanceOf(e, IOException.class);Throwables.throwIfInstanceOf(e, SecurityException.class);throw Throwables.propagate(e);
}

Guava的Throwables.propagate方法会检查传入的异常是否是运行时异常或错误。如果是,它就直接抛出;如果不是,它会将其包装在一个RuntimeException中,再抛出。
样做的目的是绕过Java的检查型异常机制,使得代码更加灵活。

总结:

  • 谨慎使用异常传播: 虽然Throwables.propagate很方便,但过度使用可能会导致真正的异常原因被掩盖。因此,只在确实需要将检查型异常转为未检查型异常时使用它。
  • 明智使用根本原因分析: getRootCause方法可以帮助找到异常的根本原因,但有时候中间层的异常信息也很重要。所以,在使用这个方法时,要根据具体情况判断。‘
  • 保留原始异常信息: 当使用Throwables类处理异常时,要确保原始异常信息不会丢失。这对于后续的问题追踪和修复至关重要。

Throwables与Java 8+的兼容性

Lambda表达式中的异常处理,在Lambda表达式中“偷偷”抛出检查型异常,而不必显式地在Lambda表达式上声明异常。

List<String> fileNames = ...; // 一些文件名
fileNames.forEach(fileName -> {try {// 对每个文件名执行某些可能抛出IOException的操作} catch (IOException e) {throw Throwables.propagate(e);}
});

结合Stream API,通过map操作处理每个元素,并利用Throwables来处理可能出现的异常。

List<String> input = ...; // 输入数据
List<String> processedData = input.stream().map(data -> {try {// 对数据进行处理,可能抛出异常return processData(data);} catch (Exception e) {throw Throwables.propagate(e);}}).collect(Collectors.toList());

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

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

相关文章

嵌入式蓝桥杯做题总结

第十二届省赛 按键代码 ——自认为比较巧妙&#xff0c;定时器3被设置为10ms进入一次中断&#xff0c;代替了HAL_Delay(10)的方法消抖&#xff1b; 运用状态机机思想实现检测多个按键检测——且分为两个状态&#xff0c;其中一个状态PB&#xff11;和PB&#xff12;的按键不…

stable-diffusion-webui-forge 介绍,安装,运行

一 stable-diffusion-webui-forge 介绍 stable-diffusion-webui-forge 的作用和stable-diffusion-webui一样&#xff0c;但性能上作了优化&#xff0c;说得上是是stable-diffusion-webui优化版&#xff0c;本人在使用stable-diffusion-webui时偶尔会有内存不够报错。本人的环境…

手写分布式配置中心(四)增加实时刷新功能(长轮询)

上一篇文章中实现了短轮询&#xff0c;不过短轮询的弊端也很明显&#xff0c;如果请求的频率较高&#xff0c;那么就会导致服务端压力大&#xff08;并发高&#xff09;&#xff1b;如果请求的频率放低&#xff0c;那么客户端感知变更的及时性就会降低。所以我们来看另一种轮询…

Mysql面试总结

基础 1. 数据库的三范式是什么&#xff1f; 第一范式&#xff1a;强调的是列的原子性&#xff0c;即数据库表的每一列都是不可分割的原子数据项。第二范式&#xff1a;要求实体的属性完全依赖于主关键字。所谓完全 依赖是指不能存在仅依赖主关键字一部分的属性。第三范式&…

UDP通信发送和接收 || UDP实现全双工通信

recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 功能: 从套接字中接收数据 参数: sockfd:套接字文件描述符 buf:存放数据空间首地址 …

基于springboot实现的幼儿园管理系统

一、系统架构 前端&#xff1a;html | layui | jquery | css 后端&#xff1a;springboot | mybatis 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及数据库 三、功能介绍 01. 登录页 02. 系统管理-用户管理 03. 系统管理-页面管理 04. 系统管理-角色管…

win11配置Mask DINO小白踩坑记录

win11配置Mask DINO踩坑记录 1 准备工作2 创建python环境和安装detectron22.1 安装前提2.2 安装流程2.2.1 cl.exe的错误2.2.2 SetuptoolsDeprecationWarning的错误 3 MaskDINO运行3.1 运行demo 前情提要&#xff1a;需要复现Mask DINO&#xff0c;但是实验室没有Linux的电脑&am…

keycloak18.0.0==本地源码启动

github下载源码&#xff0c; 版本18.0.0 java和maven的版本如下 E:\keycloak-18.0.0>java -version java version "21.0.1" 2023-10-17 LTS Java(TM) SE Runtime Environment (build 21.0.112-LTS-29) Java HotSpot(TM) 64-Bit Server VM (build 21.0.112-LTS-…

【网站项目】308学生档案管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Spring Webflux 详解

目录 0、组件对比 1、WebFlux 1、引入 2、Reactor Core 1、HttpHandler、HttpServer 3、DispatcherHandler 1、请求处理流程 4、注解开发 1、目标方法传参 2.返回值写法 5、文件上传 6、错误处理 7、RequestContext 8、自定义Flux配置 9、Filter WebFlux&am…

Linux 之二:CentOS7 的 IP 常用命令和配置及 xshell 基本使用方法

1. 进入虚拟机 点击右键---进入终端--输入 ip adrr 或 ifconfig 查看ip地址 下面输入命令 ifconfig&#xff08;注意&#xff1a;不是 ipconfig &#xff09; 或 ip addr 来查看当前系统 IP 查看到IP 后&#xff0c;比如&#xff1a;上面是 192.168.184.137 1.1 IP 常用命令…

LeetCode142题:环形链表II(python3)

代码思路&#xff1a; 双指针的第一次相遇&#xff1a; 设两指针 fast&#xff0c;slow 指向链表头部 head 。 令 fast 每轮走 2 步&#xff0c;slow 每轮走 1 步。 fast 指针走过链表末端&#xff0c;说明链表无环&#xff0c;此时直接返回 null。 如果链表存在环&#xff0c;…

web学习笔记(二十六)

目录 1.JS执行队列 1.1JS是单线程 1.2Web Worker 1.3同步和异步 1.4JS执行机制 2.location对象 2.1什么是location对象 2.2url包含的信息 2.3location对象属性 2.4location对象的方法 3.navigator对象和history对象 3.1navigator对象 3.2history对象 1.JS执行队…

初识JS

目录 javascript的作用: 浏览器如何执行JS代码&#xff1a; JS的三部分组成&#xff1a; ECMAScript: DOM: BOM: JS的三种书写导入方式&#xff1a; JS注释&#xff1a; JS的输入输出语句&#xff1a; JS变量,数据&#xff1a; 变量的使用&#xff1a; 声明变量&…

嵌入式学习第二十五天!(网络的概念)

网络&#xff1a; 可以用来&#xff1a;数据传输、数据共享 1. 网络协议模型&#xff1a; 1. OSI协议模型&#xff1a; 应用层实际收发的数据表示层发送的数据是否加密会话层是否建立会话连接传输层数据传输的方式&#xff08;数据包&#xff0c;流式&#xff09;网络层数据的…

Vue+SpringBoot打造医院门诊预约挂号系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2 科室医生档案模块2.1.3 预约挂号模块2.1.4 医院时政模块 2.2 可行性分析2.2.1 可靠性2.2.2 易用性2.2.3 维护性 三、数据库设计3.1 用户表3.2 科室档案表3.3 医生档案表3.4 医生放号…

SpringCloud Alibaba 学习

一&#xff1a;SpringCloud Alibaba介绍 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服 务的必需组件&#xff0c;方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 依托 Spring Cloud Alibaba&…

JavaScript实现点击鼠标弹钢琴的效果

思路&#xff1a; 图片设置宽900px&#xff0c;找到鼠标按下时的x坐标和img距离body的x坐标&#xff0c;两个值相减&#xff0c;然后除100取整&#xff0c;赋值给a&#xff0c;通过判断a的值来确定放出那个音乐。 完整代码&#xff1a; <!DOCTYPE html> <html lan…

MQTT连接阿里云物联网上报物模型数据

目录 1. 创建产品&#xff08;物联网平台 -> 产品 -> 创建产品&#xff09; 2. 为产品添加设备 3. 添加物模型 4. mqtt.fx连接测试 5. 调试物模型 6. 使用mqtt.fx上报温度数据 1. 创建产品&#xff08;物联网平台 -> 产品 -> 创建产品&#xff09; 我这里再新…

Java开发快速学习,Java面试题汇总

前言 面试时间将近两个小时&#xff08;期间等待二面面试官来面我的时候等了半个多小时&#xff09;面试官问的东西很多&#xff0c;还挖了好几个坑&#xff0c;一个技术点套着一个技术点的问&#xff0c;一定要做好万全的准备。问了一些基本层面上的技术点都答出来了&#xf…