第三站:Java红——异常处理的热情与挑战

### 第三站:Java红——异常处理的热情与挑战

在Java编程的征途中,异常处理是无法绕过的“红色地带”,它充满了挑战,也饱含解决问题的热情。通过合理地使用异常处理机制,我们可以编写出更加健壮、容错性强的代码。本节将深入探讨Java中的异常处理基础——`try-catch`、`finally`块以及自定义异常,通过实战代码来说明它们的运用。

#### try-catch:捕捉异常的盾牌

`try-catch`是Java异常处理的基本结构,用于捕获并处理在`try`块中可能发生的异常。

```java

public class TryCatchExample {public static void main(String[] args) {try {// 可能产生异常的代码int result = 10 / 0; // 这里会抛出ArithmeticException} catch (ArithmeticException e) {// 处理异常System.out.println("除数不能为0,发生了算术异常!");}// 其他正常执行的代码System.out.println("程序继续运行...");}
}


```
- 当`try`块中的代码执行时,如果遇到异常,会立即停止当前执行流程,转而去匹配相应的`catch`块。
- 如果捕获到的是指定的异常类型(如`ArithmeticException`),则执行对应的`catch`块内的代码。

#### finally:风雨无阻的守护

`finally`块无论是否发生异常都会被执行,常用于释放资源,如关闭文件流、数据库连接等。

```java

public class FinallyExample {public static void main(String[] args) {BufferedReader reader = null;try {reader = new BufferedReader(new FileReader("file.txt"));// 读取文件操作} catch (FileNotFoundException e) {System.out.println("文件未找到。");} catch (IOException e) {System.out.println("读取文件时发生错误。");} finally {if (reader != null) {try {reader.close();} catch (IOException e) {System.out.println("关闭文件时发生错误。");}}}System.out.println("程序结束。");}
}


```
- `finally`块确保了即使在异常情况下,资源也能被正确释放,提高了程序的健壮性。

#### 自定义异常:个性化错误信号

Java允许我们自定义异常类,以更精确地描述特定问题,增强代码的可读性和维护性。```java

public class MyException extends Exception {public MyException(String message) {super(message);}
}public class CustomExceptionExample {public static void validateAge(int age) throws MyException {if (age < 0) {throw new MyException("年龄不能为负数。");}}public static void main(String[] args) {try {validateAge(-1);} catch (MyException e) {System.out.println(e.getMessage());}}
}


```
- `MyException`继承自`Exception`,是自定义异常类。
- 在`validateAge`方法中,如果年龄小于0,则抛出自定义异常。
- `main`方法捕获并处理这个自定义异常,打印出个性化的错误信息。

通过这些实例,我们可以看到,Java的异常处理机制是一种强大的工具,它要求开发者不仅要预见潜在的错误情况,还要能够妥善处理这些异常,确保程序的稳定运行。掌握`try-catch-finally`的使用,以及学会自定义异常,是每位Java开发者必备的技能,它们让代码更加健壮,也让编程之路充满挑战与热情。

### 异常处理的热情与挑战深化:多异常捕获、嵌套try-catch及异常链

在Java异常处理的探索之路上,我们不仅要掌握基础的异常捕获和释放资源的技巧,还需要深入了解如何优雅地处理多个异常、异常的嵌套使用以及如何利用异常链传递异常信息。这些高级话题将使我们对异常处理的策略更加成熟,代码更加健壮和易于维护。

#### 多异常捕获

在实际开发中,一个`try`块可能会抛出多种类型的异常,Java允许我们用一个`catch`捕获多种异常,或者使用多个`catch`分别捕获不同类型的异常。

```java

public class MultiCatchExample {public static void multiFileOperations() {try {// 假设这里进行读取文件和数据库操作,可能抛出不同类型的异常readFile();accessDatabase();} catch (FileNotFoundException | SQLException e) { // 同时捕获两种异常System.out.println("文件不存在或数据库访问失败: " + e.getMessage());} catch (IOException e) {System.out.println("IO操作异常: " + e.getMessage());}}static void readFile() throws FileNotFoundException, IOException {}static void accessDatabase() throws SQLException {}
}


```
- 使用管道符`|`可以在一个`catch`块中捕获多种类型的异常,简化代码。
- 分别捕获不同异常可以提供更精确的错误处理逻辑。

#### 嵌套try-catch

在某些情况下,内部的代码块可能需要更精细的异常处理,这时可以使用嵌套的`try-catch`结构。```java

public class NestedTryCatchExample {public static void nestedOperations() {try {// 外层操作System.out.println("执行外层操作...");try {// 内层可能抛出异常的操作System.out.println("执行内层操作...");int[] arr = {1};System.out.println(arr[1]); // 这将抛出ArrayIndexOutOfBoundsException} catch (ArrayIndexOutOfBoundsException e) {System.out.println("内层捕获到数组越界异常。");}} catch (Exception e) {System.out.println("外层捕获到异常: " + e.getMessage());}}public static void main(String[] args) {nestedOperations();}
}


```
- 内层`try-catch`可以处理特定的异常,而外层可以捕获未被内层处理的异常,形成层次化的异常处理机制。

#### 异常链

异常链允许我们在捕获一个异常时抛出另一个异常,同时保留原始异常的信息,这对于调试和追踪异常源头非常有帮助。

```java

public class ExceptionChainExample {public static void process() throws Exception {try {// 假设这里发生了一些操作throw new IOException("原始I/O错误");} catch (IOException e) {throw new RuntimeException("处理过程中出错", e); // 将原始异常作为新异常的cause}}public static void main(String[] args) {try {process();} catch (Exception e) {System.out.println("捕获到异常: " + e.getMessage());e.printStackTrace(); // 打印堆栈跟踪,可以看到异常链}}
}


```
- 通过`throw new Exception("描述", originalException)`构造方法,创建新的异常时携带原始异常,形成了异常链。
- 使用`printStackTrace()`可以查看完整的异常链路,便于调试。

通过这些高级异常处理技巧的学习,我们能够更有效地应对复杂逻辑中的错误处理,提高代码的健壮性和可维护性。异常处理不仅仅是简单地捕获和打印异常,更是一种对程序错误情况的精心设计和管理,让代码在面对挑战时,仍能保持那份冷静和从容。

### 异常处理的热情与挑战深化:异常的抑制、使用assert断言及最佳实践

在Java异常处理的探索之旅上,我们已掌握了异常的基本捕获、多异常处理、嵌套try-catch、以及异常链的应用。接下来,我们将深入探讨异常抑制、使用`assert`断言进行调试,以及遵循异常处理的最佳实践,进一步提升我们处理异常的能力。

#### 异常抑制

从Java 7开始,异常处理新增了异常抑制功能,允许在try-with-resources语句中自动关闭资源时不传播关闭时发生的异常,而是将其抑制。```java

public class SuppressedExceptionExample {public static void main(String[] args) {try (MyResource resource1 = new MyResource("Resource 1");MyResource resource2 = new MyResource("Resource 2")) {// 模拟操作可能会导致resource1或resource2抛出异常throw new RuntimeException("操作失败");} catch (Exception e) {for (Throwable suppressed : e.getSuppressed()) {System.out.println("Suppressed Exception: " + suppressed.getMessage());}System.out.println("Caught Exception: " + e.getMessage());}}
}class MyResource implements AutoCloseable {private final String name;MyResource(String name) {this.name = name;}@Overridepublic void close() throws Exception {if ("Resource 1".equals(name)) {throw new IOException("Failed to close Resource 1");} else if ("Resource 2".equals(name)) {throw new SQLException("Failed to close Resource 2");}}
}
```
- 在try-with-resources块中,即使主代码路径抛出了异常,也会尝试关闭所有资源。关闭资源时发生的异常会被抑制,并可以通过`e.getSuppressed()`获取。#### 使用`assert`断言`assert`关键字用于在开发阶段进行调试,检查某个条件是否满足,如果不满足则抛出`AssertionError`。默认情况下,断言是禁用的,需通过`-ea`VM选项启用。```java
public class AssertExample {public static void main(String[] args) {int value = 0;assert value > 0 : "value should be positive"; // 这条断言在运行时不会执行,因为value=0}
}


```
- 断言不应用于生产环境的错误处理,而是作为开发阶段的辅助工具,确保程序状态符合预期。

#### 异常处理最佳实践

1. 明确抛出异常:尽量避免空抛出(throw new Exception()),明确异常类型,有助于调用者理解和处理。
2. 避免吞咽异常:不要随意捕获异常后不做任何处理,至少应记录日志或通知调用者。
3. 精确捕获异常:尽量精确地捕获异常类型,而不是捕获过于宽泛的异常,如直接捕获`Exception`。
4. 资源管理:使用try-with-resources或其他机制确保资源被及时关闭。
5. 文档化异常:在方法的Javadoc中明确指出可能抛出的异常,帮助调用者理解接口行为。

通过深入理解异常抑制、合理使用`assert`断言以及遵循最佳实践,我们能在异常处理这一领域达到更高的境界。异常不仅是错误的反映,更是程序健壮性的保障,体现了开发者对软件质量的热情追求和严谨态度。

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

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

相关文章

jni调用so或dll区别

在Java中通过JNI&#xff08;Java Native Interface&#xff09;调用本地代码时&#xff0c;所使用的动态库文件扩展名&#xff08;如 .dll 对于Windows或 .so 对于Unix-like系统&#xff09;取决于你的操作系统和目标平台。 DLL&#xff08;Dynamic Link Library&#xff09;…

python数据预处理

PYTHON 最流行库&#xff1a;Numpy、Matplotlib 和 Pandas。Numpy 是满足所有数学运算所需要的库&#xff0c;由于代码是基于数学公式运行的&#xff0c;因此就会使用到它。Maplotlib&#xff08;具体而言&#xff0c;Matplotlib.pyplot&#xff09;则是满足绘图所需要的库。Pa…

使用redis的setnx实现分布式锁

在Redis中&#xff0c;SETNX 是 “Set If Not Exists”&#xff08;如果不存在&#xff0c;则设置&#xff09;的缩写。这是一个原子操作&#xff0c;用于设置一个键的值&#xff0c;前提是这个键不存在。如果键已经存在,.则不会执行任何操作。 封装方法trylock&#xff0c;用…

智能超越了科技,更是一个复杂系统

智能不仅仅是科技系统&#xff0c;更是一个复杂系统。智能是一个多学科领域&#xff0c;涉及计算机科学、人工智能、神经科学、心理学、社会学、人文艺术、宗教哲学等多个学科。科技系统只是智能的一部分&#xff0c;虽然它们在处理信息和执行任务方面非常强大&#xff0c;但它…

CCF-CSP认证 2023年3月01 田地丈量

矩形重叠面积公式&#xff1a; p1与p2表示矩形A的左下角和右上角&#xff0c;用p3和p4表示矩形B的左下角和右上角。 res!(p1.x > p4.x) || (p2.x < p3.x) || (p1.y > p4.y) || (p2.y < p3.y) //对矩阵不重叠求反 矩阵重叠面积 double Len Math.min(p2_x, p4_x…

深入解析Solon路由的Url大小写匹配策略与实际应用

在数字化时代的背景下&#xff0c;企业对于采购管理的需求日益增长。为了满足这一需求&#xff0c;我们通过采用Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;构建了一个从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理平台。 Solon路由器对ur…

小米员工自爆:35岁被裁后,投百份简历无人问津,一气之下把薪资由2W调为3W,简历改成英文,结果出乎意料

“35岁”&#xff0c;就像职场里一道无形的门槛&#xff0c;压得人喘不过气。一旦迈过这道坎&#xff0c;焦虑、迷茫、恐慌&#xff0c;接踵而至。 最近&#xff0c;我的朋友老张&#xff0c;就真切地体会到了这种“中年危机”。刚过36岁生日&#xff0c;他就收到了来自小米的裁…

从0到1写一个vue2项目,按需引入element-ui的引入,npm下载路由,配置路由,路由嵌套

从0到1写一个vue2项目&#xff0c;此篇内容有element-ui的按需引入&#xff0c;npm下载路由&#xff0c;配置路由&#xff0c;路由嵌套 项目是b站上找的项目链接在此https://www.bilibili.com/video/BV1QU4y1E7qo/?p8&spm_id_frompageDriver&vd_source2c599bf1d75e3f9…

Hive之聚合类开窗函数 + 滑动求和

为什么要写这样子一个主题文章呢&#xff0c;开窗函数毫无疑问&#xff0c;超级重要&#xff0c;但是很多人可能不会遇到一些稍微小众的业务需求&#xff0c;比如说滑动求和。这里带着业务&#xff0c;一并让大家熟悉一些&#xff0c;高阶函数的应用。 0&#xff0c;开窗函数和…

Docker搭建MySQL主从复制

Docker部署MySQL主从复制 文章目录 Docker部署MySQL主从复制一、构建MySQL镜像二、构建systemctl管理MySQL服务镜像三、运行容器四、登录容器4.1、配置master4.2、配置slave 五、授权从库六、更改UUID七、连接主数据库八、验证 一、构建MySQL镜像 我自己是使用的Dockerfile构建…

【JAVA SE】抽象类和接口

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;JAVA 个人主页&#xff1a;Celias blog~ 目录 引言 一、抽象类 1.1 抽象类的定义 1.2 抽象方法 1.3 抽象…

大厂边缘组VS小厂核心组,要怎么选?

有问必答 最近有粉丝提问&#xff1a;大厂边缘组VS小厂核心组&#xff0c;怎么选&#xff1f; 这确实是个好问题&#xff0c;读者老爷们可以先问下自己&#xff1a;如果有一份月薪2W在大厂边缘组打螺丝的Offer且不加班&#xff0c;另外还有一份月薪2W5&#xff0c;在小厂核心…

华为坤灵管理型交换机S300,S500,S310,S210,S220,S200 web端开局配置

一. 准备线缆 笔记本或没有COM口的电脑,需准备转接线,并安装好随线光盘的驱动,检查设备管理器中COM口是否正常 2.连接电脑与交换机的CONSOLE口 二&#xff0c;准备软件putty。 Download PuTTY: latest release (0.81) 配置步骤如下&#xff1a; 开启HTTP服务。设置https://1…

你知道SPI的原理以及实现?

1、什么是SPI&#xff1f; SPI&#xff08;Service Provider Interface&#xff09;&#xff0c;是JDK内置的一种服务提供发现机制&#xff0c;可以用来启用框架扩展和替换组件&#xff0c;主要是被框架的开发人员使用&#xff0c;比如 java.sql.Driver 接口&#xff0c;其他不…

【conda】解决conda activate无效的问题

conda activate 虚拟环境名字执行上述命令失效&#xff0c;提示如下信息&#xff1a; 经查询&#xff0c;原因是新版的 conda 不再使用 activate 来激活虚拟环境&#xff0c;而是改用&#xff1a; source activate 虚拟环境名退出虚拟环境还是&#xff1a; conda deactivate…

sqlite基本操作

简介 文章目录 简介1.数据库的安装2.数据库命令&#xff1a;API&#xff0c;创建表单代码 csprintf&#xff08;&#xff09;getchar和scanf&#xff08;&#xff09; 1.数据库的安装 sudo dpkg -i *.deb这个报错表明出现依赖问题 用这个命令后再试试sudo apt --fix-broken in…

Apache来源于北美印第安部落?

Apache HTTP服务器&#xff0c;通常简称为Apache&#xff0c;是一个由Apache软件基金会&#xff08;Apache Software Foundation&#xff0c;简称ASF&#xff09;维护的开源网页服务器软件。以下是Apache的前世今生的概述&#xff1a; 起源&#xff1a; Apache的起源可以追溯…

计算机组成原理----浮点数的表示和运算

目录 一.浮点数的表示 1.浮点数的作用和基本原理 2.浮点数的规格化 3.浮点数的表示范围 二.IEEE 754标准 三.浮点数的加减运算 1.加减运算 2.强制类型转换 一.浮点数的表示 1.浮点数的作用和基本原理 定点数在字节数固定的情况下&#xff0c;能表示的数字是很有限的&…

输入15个整数,计算并输出15个整数的和,并输出其中最大值和最小值;

输入15个整数&#xff0c;计算并输出15个整数的和&#xff0c;并输出其中最大值和最小值&#xff1b; #include<stdio.h> int main() {int i0,s0,max,min,jg0,jp0,og0,omax; int a[15]{12,13,14,16,17,18,19,10,1,2,3,4,5,6,7}; maxa[0],mina[0]; for(i0,s0;i<15;i) …

Android编程用什么语言:深入探索与开发实践

Android编程用什么语言&#xff1a;深入探索与开发实践 在移动应用开发的浩瀚海洋中&#xff0c;Android平台无疑占据了重要的地位。而对于那些渴望投身于此领域的开发者们来说&#xff0c;选择何种编程语言进行Android编程&#xff0c;无疑是一个关键且充满困惑的问题。本文将…