【JavaSE专栏67】谈谈异常的那些事,学会预判异常、捕获异常、转移异常

简介: 【JavaSE专栏67】谈谈异常的那些事,学会预判异常、捕获异常、转移异常

本文讲解了 Java 中异常的基础概念及语法,并给出了样例代码。异常是指程序在运行过程中遇到的错误或异常情况,当程序出现异常时,会抛出一个异常对象,这会中断正常的程序执行流程,并将控制权转移到异常处理机制。


一、什么是异常

在 Java 中,异常是指程序在运行过程中遇到的错误或异常情况

当程序出现异常时,会抛出一个异常对象,这会中断正常的程序执行流程,并将控制权转移到异常处理机制。

异常可以分为两种类型,受检异常非受检异常

  1. 受检异常:受检异常是指编译器要求程序必须显式地进行处理或者声明抛出的异常。这些异常通常代表程序中的一些预料到的错误或异常情况,需要程序员在代码中进行处理。例如,IOException(输入输出异常)或 SQLException(数据库异常)等。
  2. 非受检异常:非受检异常是指编译器不要求程序显式地处理或者声明抛出的异常。这些异常通常是由程序中的逻辑错误或者运行时错误引起的,无法在编译期间被发现,而是在程序运行时抛出。例如,NullPointerException(空指针异常)、ArrayIndexOutOfBoundsException(数组索引越界异常)或 ArithmeticException(算术异常)等。

处理异常的方式是使用 try-catch 语句块来捕获并处理异常。在 try 块中编写可能抛出异常的代码,而在 catch 块中处理异常并采取相应的措施,例如输出错误信息或进行其他操作。

此外,还可以使用 throws 关键字来声明方法可能抛出的异常,使得调用该方法的代码必须对异常进行处理或继续声明抛出。

异常处理机制的目的是增加程序的健壮性和容错性,使程序可以优雅地处理异常情况,保证程序的正常运行。


二、异常如何产生

在 Java 中,异常是由于程序在运行过程中遇到了错误或异常情况而导致的,以下是 4 44 种常见的异常产生的情况,请同学们认真学习。

  1. 运行时错误:这些错误是由于程序的逻辑错误或运行时错误导致的。例如,空指针引用、数组索引越界、算术异常等。
  2. 调用方法抛出异常:当调用一个方法时,如果该方法声明了可能抛出异常,而在方法内部发生了异常情况,就会抛出该异常。例如,读写文件时可能发生的 IOException 异常。
  3. 显式抛出异常:在代码中可以使用 throw 关键字来显式地抛出异常。这通常是在程序中检测到错误或异常情况时,人为地抛出异常。例如,自定义异常类并抛出特定的异常对象。
  4. JVM 抛出异常:有一些异常是由 Java 虚拟机自动抛出的,这些异常通常表示严重的错误或系统级异常。例如,OutOfMemoryError 表示内存不足,StackOverflowError 表示栈溢出等。

无论是哪种情况,当程序发生异常时,会创建一个异常对象,并且程序的正常执行流程会被中断。异常对象会被抛出,然后在调用栈中寻找能够处理该异常的代码块。

  • 如果找到了合适的异常处理器(catch 块),则异常会被捕获并在处理器中进行相应的处理。
  • 如果没有找到合适的异常处理器,异常会一直向上层调用栈传递,直到遇到能够处理异常的地方或者程序终止。

通过合理地处理异常,可以增加程序的健壮性和容错性,保证程序的稳定性和可靠性。


三、异常的种类

在 Java 中,异常可以分为三大类,可检查异常(、运行时异常错误,请同学们认真学习。

  1. 可检查异常:这些异常在编译时期就被检查出来,编译器会强制要求进行处理或者声明抛出。它们通常代表程序中的一些预料到的错误或异常情况,需要程序员在代码中进行处理。常见的可检查异常包括:IOExceptionSQLExceptionClassNotFoundException 等。
  2. 运行时异常:这些异常表示程序在运行过程中发生的错误或异常情况,属于非受检异常。它们通常是由程序的逻辑错误或者运行时错误引起的,无法在编译期间被发现。编译器不会强制要求进行处理或者声明抛出。常见的运行时异常包括:NullPointerExceptionArrayIndexOutOfBoundsExceptionArithmeticException 等。
  3. 错误:错误表示严重的问题或系统级异常,通常是由 Java 虚拟机自动抛出的,错误一般无法通过程序进行处理或者恢复,常见的错误包括:OutOfMemoryErrorStackOverflowError 等。

处理可检查异常和运行时异常可以通过使用 try-catch 语句块来捕获并处理异常,也可以使用 throws 关键字在方法声明中抛出异常,对于错误,通常无法进行有效的处理,最常见的做法是让程序终止。

在编写代码时,应该根据实际情况来决定如何处理异常。

对于可检查异常,应该根据具体业务需求进行合适的处理,例如提供错误信息、重试操作或回退操作等。

对于运行时异常,通常是由于代码中的逻辑错误引起的,应该尽量避免发生这些异常,并进行合适的边界检查和异常处理。

对于错误,无法通过程序进行恢复,应该在程序设计阶段尽量避免出现错误,或者在出现错误时进行相应的系统级处理。


四、如何捕获异常

在 Java 中,可以使用 try-catch 语句块来捕获异常。try 块中编写可能抛出异常的代码,而 catch 块用于处理捕获到的异常,以下是一个示例代码,请同学们认真学习。

public class ExceptionHandlingExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("An arithmetic exception has occurred: " + e.getMessage());
        }
    }
    public static int divide(int num1, int num2) {
        return num1 / num2;
    }
}

在上述代码中,我们定义了一个 divide() 方法,用于除法运算。

main() 方法中,我们调用了 divide(10, 0),这是一个可能会抛出 ArithmeticException 的操作。

为了捕获这个异常,我们将该操作放在一个 try 块中,并在 catch 块中处理。

当程序执行到 divide(10, 0) 时,由于除数为0,会抛出 ArithmeticException 异常。

然后,异常会被 catch 块捕获,执行相应的处理逻辑,即输出异常信息:An arithmetic exception has occurred: / by zero

通过 try-catch 语句块,我们可以捕获并处理可能抛出的异常,避免程序的异常导致程序崩溃,提高程序的健壮性和容错性。在实际开发中,可以根据具体情况捕获不同类型的异常,并进行相应的处理操作。


五、异常面试题

一、Java中的异常分为哪几种类型?

  • 可检查异常
  • 运行时异常
  • 错误

二、如何捕获和处理异常?

  • 使用 try-catch 语句块来捕获异常,在 catch 块中处理异常情况。
  • 可以使用多个 catch 块来捕获不同类型的异常。
  • 可以使用 finally 块来执行一些无论是否发生异常都需要执行的代码。

三、try-catch-finally语句块之间的执行顺序是怎样的?

  • 首先执行try块中的代码。
  • 如果 try 块中发生了异常,则跳转到对应的 catch 块进行处理。
  • 如果 try 块中没有发生异常,则跳过 catch 块。
  • 无论是否发生异常,finally 块中的代码都会执行。

四、throws 关键字和 throw 关键字有什么区别?

  • throws 关键字是用于方法声明中,表明该方法可能会抛出某些异常,由调用该方法的代码负责处理异常。
  • throw 关键字是用于在程序中显式抛出异常,可以抛出自定义异常或已有的异常类型。

五、RuntimeException 和 CheckedException 之间的区别是什么?

  • RuntimeException 是运行时异常,不需要在方法中显式地声明抛出,也可以不进行捕获处理。
  • CheckedException 是可检查异常,必须在方法中声明抛出或捕获处理。

六、什么时候应该使用自定义异常?

  • 当已有的 Java 预定义异常不足以描述特定的错误或异常情况时,可以使用自定义异常来表示特定的错误或异常情况。

六、总结

本文讲解了 Java 中异常的基础概念及语法,并给出了样例代码,在下一篇博客中,将讲解 Java 异常的捕获和处理。


相关文章
|
存储 人工智能 C#
【Unity 3D】C#中数组、集合、栈、队列、哈希表、字典的讲解(附测试代码)
【Unity 3D】C#中数组、集合、栈、队列、哈希表、字典的讲解(附测试代码)
402 0
|
8月前
|
编解码 文字识别 语音技术
MiniCPM-o 2.6:流式全模态,端到端,多模态端侧大模型来了!
MiniCPM-o 2.6 是 MiniCPM-o 系列的最新、性能最佳模型。该模型基于 SigLip-400M、Whisper-medium-300M、ChatTTS-200M 和 Qwen2.5-7B 构建,共 8B 参数,通过端到端方式训练和推理。相比 MiniCPM-V 2.6,该模型在性能上有了显著提升,并支持了实时语音对话和多模态流式交互的新功能。
1147 70
|
IDE 测试技术 开发工具
NumPy 代码调试与错误处理
【8月更文第30天】NumPy 是 Python 中用于科学计算的核心库之一,提供了高性能的多维数组对象和大量的数学函数。尽管 NumPy 提供了许多方便的功能,但在实际编程过程中难免会遇到各种各样的问题。本文将介绍一些调试 NumPy 代码的技巧,并讨论如何处理常见的错误。
723 2
|
10月前
|
机器学习/深度学习 消息中间件 监控
监控工具实现实时监测的方法
监控工具实现实时监测的方法
393 11
|
10月前
|
数据采集 前端开发 JavaScript
捕捉页面的关键元素:用CSS选择器与Puppeteer自动抓取
本文介绍了如何使用 Puppeteer 结合 CSS 选择器抓取动态网页中的关键元素,以亚航网站的特价机票信息为例,通过设置代理 IP、User-Agent 和 Cookie 等技术手段,有效提升爬虫策略,实现高效、稳定的爬取。
290 5
捕捉页面的关键元素:用CSS选择器与Puppeteer自动抓取
|
11月前
|
安全 Java 数据库
shiro学习一:了解shiro,学习执行shiro的流程。使用springboot的测试模块学习shiro单应用(demo 6个)
这篇文章是关于Apache Shiro权限管理框架的详细学习指南,涵盖了Shiro的基本概念、认证与授权流程,并通过Spring Boot测试模块演示了Shiro在单应用环境下的使用,包括与IniRealm、JdbcRealm的集成以及自定义Realm的实现。
218 3
shiro学习一:了解shiro,学习执行shiro的流程。使用springboot的测试模块学习shiro单应用(demo 6个)
|
11月前
|
存储 SQL NoSQL
数据库技术深度探索:从关系型到NoSQL的演变
【10月更文挑战第21天】数据库技术深度探索:从关系型到NoSQL的演变
244 1
|
小程序 JavaScript 开发者
微信小程序构建npm
微信小程序构建npm
643 4
|
负载均衡 算法 网络虚拟化
ensp中链路聚合配置命令
链路聚合(Link Aggregation)是结合多条物理链路形成逻辑链路的技术,提升网络带宽、增强冗余性和优化负载均衡。在高带宽、高可靠性及负载均衡需求的场景如服务器集群、数据中心等中广泛应用。配置包括手动和自动模式,手动模式下,如LSW1和LSW2,通过`int eth-trunk`、`trunkport`等命令配置接口和成员链路。自动模式下,如SW3和LSW4,使用LACP协议动态聚合,通过`mode lacp-static`和`load-balance dst-mac`命令设置。配置后,使用`dis eth-trunk`检查聚合状态。
1689 1
ensp中链路聚合配置命令
|
SQL 开发框架 安全
CTF基础 --隐写术与密码学编码
CTF基础 --隐写术与密码学编码
184 0