java:Java中的异常处理

目录

异常的概念与体系结构

异常的概念:

异常的体系结构:

异常的处理方式

防御式编程:

异常的抛出:

异常的捕获:

finally:

代码示例:

异常的处理流程

自定义异常类

举例: 


异常的概念与体系结构

异常的概念:

在程序中不正常行为称为异常,如算术异常、数组越界异常、空指针异常等。

例如:

public class ExceptionDemo {public static void main(String[] args) {// 示例算术异常try {int result = 10 / 0; // 除以0会抛出算术异常} catch (ArithmeticException e) {System.out.println("算术异常:" + e.getMessage());}// 示例数组越界异常try {int[] arr = {1, 2, 3};System.out.println(arr[100]); // 访问数组越界会抛出数组越界异常} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常:" + e.getMessage());}// 示例空指针异常try {String str = null;System.out.println(str.length()); // 对空指针调用方法会抛出空指针异常} catch (NullPointerException e) {System.out.println("空指针异常:" + e.getMessage());}}
}

异常的体系结构:

        Throwable是异常体系的顶层类,派生出Error和Exception两个重要的子类,分为编译时异常和运行时异常。


异常的处理方式

防御式编程:

LBYL(Look Before You Leap):在操作之前进行充分的检查,事前防御型。例如,在代码中先检查条件,再执行操作,以避免异常情况的发生。

EAFP(It's Easier to Ask Forgiveness than Permission):先操作,遇到问题再处理,事后认错型。这种方式更关注正常流程,代码更清晰,容易理解。

异常的抛出:

使用throw关键字抛出异常对象,将错误信息告知给调用者。抛出的异常对象必须是Exception或其子类对象,根据异常类型不同,处理方式也不同。

异常的捕获:

通过try-catch捕获并处理异常,可以在catch块中对捕获到的异常进行具体处理。如果异常无法在当前方法中处理,可以继续向上抛出或交给调用者处理。

异常声明throws:在方法声明时使用throws关键字将异常抛给方法的调用者处理,提醒调用者处理异常。

finally:

finally块用于资源清理的扫尾工作,无论是否发生异常,finally中的代码都会被执行一般用于释放资源,确保资源得到正确释放。

代码示例:

public class ExceptionHandlingDemo {public static void main(String[] args) {// 防御式编程示例 - LBYLString str = null;if (str != null) {System.out.println(str.length()); // 不会执行,避免空指针异常}// 防御式编程示例 - EAFPint[] arr = {1, 2, 3};try {System.out.println(arr[100]); // 尝试访问数组越界} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常:" + e.getMessage());}// 异常的抛出示例try {validateAge(-5); // 抛出自定义异常} catch (IllegalArgumentException e) {System.out.println("年龄不能为负数:" + e.getMessage());}// 异常的捕获示例try {int result = divide(10, 0); // 抛出算术异常} catch (ArithmeticException e) {System.out.println("算术异常:" + e.getMessage());}// finally示例try {System.out.println("Try block");} finally {System.out.println("Finally block - resource cleanup");}}// 自定义异常类static void validateAge(int age) {if (age < 0) {throw new IllegalArgumentException("年龄不能为负数");}}// 抛出算术异常static int divide(int a, int b) {if (b == 0) {throw new ArithmeticException("除数不能为0");}return a / b;}
}

在上述代码中,演示了防御式编程中的LBYL和EAFP方式,异常的抛出和捕获,以及finally块的使用。通过这些示例,展示了不同的异常处理方式在实际代码中的应用。


异常的处理流程

  • 程序首先执行try中的代码块
  • 如果try中的代码块出现异常,程序会立即跳转到对应的catch块进行异常处理
  • 如果找到匹配的异常类型,就会执行对应的catch块中的代码
  • 如果没有找到匹配的异常类型,异常会被向上抛出,继续传递给上层调用者
  • 无论是否找到匹配的异常类型,finally块中的代码都会被执行,用于进行资源清理等操作。
  • 如果异常一直向上传递到main方法仍未被处理,最终会交给JVM处理,导致程序异常终止。

下面是一个示例代码,演示了完整的异常处理流程:

public class ExceptionHandlingFlow {  public static void main(String[] args) {try {int result = divide(10, 0); // 抛出算术异常} catch (ArithmeticException e) {System.out.println("算术异常:" + e.getMessage());// 继续向上抛出异常throw e;} finally {System.out.println("finally块中的代码一定会执行");}}// 抛出算术异常static int divide(int a, int b) {try {if (b == 0) {throw new ArithmeticException("除数不能为0");}return a / b;} catch (ArithmeticException e) {System.out.println("捕获到算术异常:" + e.getMessage());// 继续向上抛出异常throw e;} finally {System.out.println("divide方法的finally块中的代码一定会执行");}}
}

运行结果:

在上述代码中,通过try-catch-finally块展示了完整的异常处理流程。无论是否出现异常,finally块中的代码都会被执行,用于进行必要的资源清理操作。这样可以确保程序在异常情况下也能够正常运行并保持稳定性。


自定义异常类

  • 自定义异常类继承自Exception或RuntimeException,用于表示实际开发中遇到的特定异常。
  • 可以实现带有String类型参数的构造方法,用于说明异常的原因。
  • 自定义异常通常继承自Exception或RuntimeException,分为受查异常和非受查异常。

举例: 

// 自定义用户名异常类,继承自Exception,表示用户名错误
class UserNameException extends Exception {public UserNameException(String message) {super(message);}
}// 自定义密码异常类,继承自Exception,表示密码错误
class PasswordException extends Exception {public PasswordException(String message) {super(message);}
}public class CustomExceptionExample {// 模拟用户登录,抛出自定义异常public static void login(String userName, String password) throws UserNameException, PasswordException {if (!userName.equals("admin")) {throw new UserNameException("用户名错误");}if (!password.equals("123456")) {throw new PasswordException("密码错误");}System.out.println("登录成功");}public static void main(String[] args) {try {login("admin", "12345"); // 模拟登录,抛出异常} catch (UserNameException e) {System.out.println("用户名异常:" + e.getMessage());// 可以在此处处理用户名异常} catch (PasswordException e) {System.out.println("密码异常:" + e.getMessage());// 可以在此处处理密码异常}}
}

在上述代码中,我们定义了两个自定义异常类UserNameExceptionPasswordException,分别用于表示用户名错误和密码错误的异常。这些异常类继承自Exception,表示受查异常,需要在方法声明中进行处理或抛出。在login方法中模拟用户登录过程,如果用户名或密码错误,则抛出相应的自定义异常。在main方法中通过try-catch块捕获并处理这些自定义异常,确保程序在异常情况下能够正常运行。

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

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

相关文章

管理 Python 项目的艺术:在 PyCharm 中使用虚拟环境(以BPnP为例)

在 PyCharm 中使用虚拟环境对于 Python 项目开发具有多方面的重要作用&#xff0c;这些作用体现在提升项目管理的效率、保障代码的可运行性以及维护项目的长期稳定性等方面。以下是使用虚拟环境的几个关键好处&#xff1a; 1. 依赖管理和隔离 虚拟环境允许每个项目拥有…

污水处理设备运维注意事项有哪些

污水处理设备的运维是确保污水处理效率和处理质量的关键环节。良好的运维不仅可以延长设备的使用寿命&#xff0c;还能确保污水处理过程的稳定性和可靠性。以下是一些污水处理设备运维的重要注意事项&#xff1a; 1. 定期检查和维护 设备检查&#xff1a;定期对污水处理设备进…

力扣-1844.将所有数字用字符替换

思路&#xff1a; 1. class Solution:&#xff1a;定义了一个名为 Solution 的类&#xff0c;用于包装解决问题的方法。 2. def replaceDigits(self, s: str) -> str:&#xff1a;定义了一个名为 replaceDigits 的方法&#xff0c;该方法接受一个字符串 s 作为参数&#x…

OSPF的LSA详解

一、什么是LSA&#xff1f;LSA作用&#xff1f; 在OSPF协议中&#xff0c;LSA全称链路状态通告&#xff0c;主要由LSA头部信息&#xff08;LSA摘要&#xff09;和链路状态组成。部分LSA只有LSA头部信息&#xff0c;无链路状态信息。使用LSA来传递路由信息和拓扑信息&#xff0c…

解决Mac使用Vscode无法调用外部终端

前言 今天遇到一个很奇怪的问题&#xff0c;之前好好的用Vscode还能调用外部终端&#xff0c;怎么今天不行了&#xff1f;问题出在哪里呢&#xff1f;请听我娓娓道来。 检查配置文件 我查看了一下配置文件&#xff0c;发现配置文件都是调用外部控制台&#xff0c;没毛病啊。 …

linux入门到精通-第十一章-进程间通信(无名管道)

目录 参考概念**进程通信的目的&#xff1a;**Linux 操作系统支持的主要进程间通信的通信机制: 无名管道概述pipe函数建立无名管道父子进程使用无名管道通信 管道读写特点设置非阻塞的方法查看管道缓冲区命令查看管道缓冲区函数 参考 视频教程 概念 进程是一个独立的资源分配…

Jmeter(十二) - 从入门到精通 - JMeter逻辑控制器 - 终篇(详解教程)

宏哥微信粉丝群&#xff1a;https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 Jmeter官网对逻辑控制器的解释是&#xff1a;“Logic Controllers determine the order in which Samplers are processed.”。 意思是说&#xff0c;逻辑控制器可以控制采样…

Fully Animated Cats

这个包可以用于任何类型的游戏,作为主要角色,敌人,猎物,或其他任何东西。该软件包提供90个高质量动画、10种不同风格、实时毛发、6个LOD 控制器/动画师不包括在内。此包仅适用于模型和动画(以及纹理和材质)。 这是你可以用这个资产实现的视频(这个移动是在另一个游戏引擎…

【管理咨询宝藏83】某大型集团管控诊断报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏83】某大型集团管控诊断报告 【格式】PDF版本 【关键词】管控诊断、人力资源、组织架构 【核心观点】 - 集团跨越式发展的组织瓶颈&#xff0c…

星域社区原版APP源码/社区交友App源码/动态圈子群聊php源码

简介 初始版本是由RuleAPP规则之树开发的&#xff0c;而星域社区则是在此基础上进行了二次开发和美化。作者花了近一年的时间来打磨它&#xff0c;现在即将推出Pro版。如果你只想免费使用的话&#xff0c;可以使用原始的RuleAPP版本。但是&#xff0c;如果你想要获得更好的美观…

如何进行制造设备数据汇集,发挥数据的价值?

数字化转型正深刻推动制造企业实现远程监控、提高生产效率、降低生产成本、优化产品质量及明晰精细化方向。并且工业互联网的发展离不开工业数据的应用&#xff0c;而制造设备数据汇集正是应用的基础。但制造设备数据汇集存在以下难点及痛点&#xff1a; 1、安全把控难 关键的…

STM32之串口中断接收丢失数据

五六年没搞STM32了&#xff0c;这个项目一切都挺顺利&#xff0c;万万没想到被串口接收中断恶心到了。遇到的问题很奇怪 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_index], LCD_UART_LEN); 这个代码中 LCD_UART_LEN1的时候&#xff0c;接收过来的数据&#xff0c;数…