Java异常(Exception)讲解(/try/catch/throw/throws/finally关键字/异常处理流程/自定义异常)

news2024/9/19 23:37:17

欢迎访问作者Github:Joeysoda/Github_java: Study java

在 Java 中,异常是程序在执行过程中发生的非正常行为。理解并正确处理异常是编写健壮、可靠代码的关键。下面我们将详细讲解 Java 的异常处理机制,涵盖异常体系结构、异常的分类、异常的处理流程、以及关键字 trycatchthrowthrowsfinally 的使用。


 

目录

1. 异常的体系结构

1.1 Throwable 类

1.2 Error 类

1.3 Exception 类

1.4 异常的分类

2. 异常的处理

2.1 防御性编程策略

2.2 异常的抛出

2.3 异常的捕获

2.3.1 throws 声明

2.3.2 try-catch 捕获

2.3.3 finally 块

面试题:finally 和 try-catch-finally 后的代码都会执行,为什么还要有 finally?

3. 面试题解析

3.1 throw 和 throws 的区别

3.2 finally 中的语句一定会执行吗?

4. 自定义异常类

自定义异常注意事项:

总结:异常的处理流程


1. 异常的体系结构

1.1 Throwable

Java 中所有异常类都继承自 java.lang.Throwable,它是 Java 中异常体系的根类。Throwable 有两个直接子类:

  • Error:表示系统级错误,是 JVM 无法处理的严重问题,例如 StackOverflowErrorOutOfMemoryError。这些错误通常由 JVM 抛出,程序无法恢复或处理这些错误。
  • Exception:表示程序运行过程中可以预期并可以通过代码处理的异常,例如 IOExceptionNullPointerException 等。
1.2 Error
  • Error 类代表了 JVM 运行过程中出现的严重错误,程序员通常不需要或无法处理这些错误,属于系统级错误。
  • 典型的 Error
    • StackOverflowError:栈溢出错误。
    • OutOfMemoryError:内存溢出错误。
1.3 Exception
  • Exception 类是应用程序可以通过代码进行捕获和处理的异常类。典型的异常包括:
    • ArithmeticException:算术异常(如除以 0)。
    • ArrayIndexOutOfBoundsException:数组越界异常。
    • NullPointerException:空指针异常。
1.4 异常的分类
  • 编译时异常(Checked Exception)

    • 编译时异常是在代码编译阶段需要强制处理的异常。如果程序员没有正确处理这些异常,编译器会报错,无法通过编译。常见的编译时异常有 IOExceptionSQLException
    • 处理方式:需要通过 try-catchthrows 来处理。
  • 运行时异常(Unchecked Exception/RuntimeException)

    • 运行时异常是在程序运行时发生的异常,通常是由于编程错误引起的。这类异常不要求在编译时必须处理,程序可以选择不捕获此类异常,直接由 JVM 处理。常见的运行时异常包括 NullPointerExceptionArrayIndexOutOfBoundsException
    • 处理方式:可以不用强制处理,但建议通过良好的编程习惯来避免这些错误。

2. 异常的处理

2.1 防御性编程策略
  • LBYL(Look Before You Leap):事前检查。在执行操作之前,检查是否可能发生错误。这是一种预防性编程方法。

  • 示例:
    if (list != null && list.size() > 0) {
        System.out.println(list.get(0));
    }
    

    EAFP(Easier to Ask for Forgiveness than Permission):事后处理。这是一种容错性编程方法,不做过多检查,直接操作,若发生异常再进行处理。

  • 示例:
    try {
        System.out.println(list.get(0));
    } catch (NullPointerException e) {
        System.out.println("列表为空!");
    }
    
2.2 异常的抛出

在 Java 中,可以使用 throw 关键字手动抛出异常。常见的异常抛出场景包括参数校验失败等。

注意事项

  1. throw 必须写在方法体内
  2. 抛出的对象必须是 Throwable 的子类(ExceptionError)。
  3. 如果抛出的是 RuntimeException 或其子类,则可以不强制捕获或声明,由 JVM 处理。
  4. 如果抛出的是编译时异常(Checked Exception),调用者必须处理,否则无法通过编译。

示例

public void validateAge(int age) {
    if (age < 18) {
        throw new IllegalArgumentException("年龄必须大于18");
    }
}
2.3 异常的捕获

Java 提供了 try-catch 机制来捕获和处理异常。程序可以在 try 块中编写可能会抛出异常的代码,如果出现异常,就会跳到 catch 块中处理。

2.3.1 throws 声明

当一个方法内部可能抛出异常但不处理时,可以通过 throws 关键字将异常抛给上层调用者。

注意事项

  1. throws 必须跟在方法参数列表之后。
  2. throws 后的异常必须是 Exception 或其子类。
  3. 如果方法可能抛出多个异常,必须列出多个异常类型,或声明父类即可。

示例

public void readFile(String path) throws IOException {
    FileReader fileReader = new FileReader(path);
}
2.3.2 try-catch 捕获
  • try:包含可能发生异常的代码。
  • catch:捕获异常并处理。

示例

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("除数不能为0");
}
2.3.3 finally
  • finally 块中的代码无论是否发生异常,都会执行,常用于资源清理操作。
  • 典型场景:关闭文件、释放数据库连接、关闭网络连接等。

示例

try {
    FileReader file = new FileReader("test.txt");
} catch (FileNotFoundException e) {
    System.out.println("文件未找到");
} finally {
    System.out.println("最终的资源清理操作");
}
面试题:finallytry-catch-finally 后的代码都会执行,为什么还要有 finally
  • finally 块的意义在于:无论 try 中是否抛出异常,finally 块的代码一定会执行。即使在 trycatch 块中发生 returnfinally 仍会被执行。
  • try-catch-finally 后的代码不一定能执行到,因为如果 trycatch 中有 return异常终止,后续代码就不会执行,但 finally 会被执行。

3. 面试题解析

3.1 throwthrows 的区别
  • throw:用于显式抛出异常。它是用于在方法内部手动抛出异常的。

throw new IllegalArgumentException("无效参数");
  • throws:用于声明异常,表示当前方法可能抛出异常,需要调用者处理。它用于方法声明中,放在参数列表后面。

3.2 finally 中的语句一定会执行吗?
  • 是的finally 中的代码通常会执行,无论是否抛出了异常。但在某些极端情况下,finally 中的代码可能不会执行,例如:
    • 程序在 trycatch 中调用了 System.exit() 退出 JVM。
    • JVM 崩溃,或系统中断。
    • 程序所在的线程被强制终止。

4. 自定义异常类

在 Java 中,程序员可以自定义异常类,通常用于封装业务逻辑中的异常信息。自定义异常类通常继承自 ExceptionRuntimeException

自定义异常注意事项
  1. 继承自 Exception 的异常是受检异常,调用者必须处理。
  2. 继承自 RuntimeException 的异常是非受检异常,调用者可以选择不处理,直接交给 JVM 处理。

示例:自定义异常类

class AgeException extends Exception {
    public AgeException(String message) {
        super(message);
    }
}

public void setAge(int age) throws AgeException {
    if (age < 18) {
        throw new AgeException("年龄不能小于18");
    }
}

总结:异常的处理流程

  1. 程序执行 try中的代码。
  2. 如果 try 中的代码出现异常,执行会停止,检查 catch 块中的异常类型是否匹配。
    • 如果匹配,执行 catch 中的代码。
    • 如果没有找到匹配的 catch,异常会继续向上层调用者传播。
  3. 无论是否匹配到异常类型,finally 块中的代码都会执行
  4. 如果异常没有被任何地方捕获,最终会传递到 main 方法,程序会异常终止。

通过正确的异常处理机制,程序可以更好地处理运行时的错误,保持稳定性和健壮性。

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

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

相关文章

C++:string 类详解

目录 简介 使用 初始化(构造函数、拷贝构造函数) 析构函数 赋值运算符重载(operator) 成员常量(npos) 运算符重载[ ](operator[ ]) size() 和 length() 迭代器( begin() 和 end() ) 范围 for 迭代器和范围 for 的比较 反向迭代器( rbegin() 和 rend() ) const 迭…

每日刷题(算法)

我们N个真是太厉害了 思路&#xff1a; 我们先给数组排序&#xff0c;如果最小的元素不为1&#xff0c;那么肯定是吹牛的&#xff0c;我们拿一个变量记录前缀和&#xff0c;如果当前元素大于它前面所有元素的和1&#xff0c;那么sum1是不能到达的值。 代码&#xff1a; #def…

elasticsearch实战应用

Elasticsearch(ES)是一种基于分布式存储的搜索和分析引擎&#xff0c;目前在许多场景得到了广泛使用&#xff0c;比如维基百科和github的检索&#xff0c;使用的就是ES。本文总结了一些使用心得体会&#xff0c;希望对大家有所帮助。 一、技术选型 说到全文搜索大家肯定会想到…

软件测试 BUG 篇

目录 一、软件测试的生命周期 二、BUG 1. bug的概念 2. 描述bug的要素 3. bug的级别 4. bug的生命周期 5. 与开发产生争执怎么办&#xff1f;&#xff08;面试高频考题&#xff09; 5.1 先检查自身&#xff0c;是否bug描述不清楚 5.2 站在用户角度考虑并抛出问题 5.3 …

[vue2+axios]下载文件+文件下载为乱码

export function downloadKnowledage(parameter) {return axios({url: /knowledage/download,method: GET,params: parameter,responseType: blob}) }添加 responseType: blob’解决以下乱码现象 使用触发a标签下载文件 downloadKnowledage(data).then((res) > {let link …

PHP及Java等其他语言转Go时选择GoFly快速快速开发框架指南

概要 经过一年多的发展GoFly快速开发框架已被一千多家科技企业或开发者用于项目开发&#xff0c;他的简单易学得到其他语言转Go首选框架。且企业版的发展为GoFly社区提供资金&#xff0c;这使得GoFly快速框架得到良好的发展&#xff0c;GoFly技术团队加大投入反哺科技企业和开…

模版进阶(template)

1.非类型模版参数 模版参数分类类型形参与非类型形参。 ① 类型形参&#xff1a;出现在在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 ② 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数当…

Java键盘输入语句

编程输入语句 1.介绍:在编程中&#xff0c;需要接受用户输入的数据&#xff0c;就可以使用键盘输入语句来获取。 2.步骤&#xff1a; 1&#xff09;导入该类的所在包&#xff0c;java.util.* 2)创建该类对象&#xff08;声明变量&#xff09; 3&#xff09;调用里面的功能 3…

[2025]医院健康陪诊系统(源码+定制+服务)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

计算机毕业设计 奖学金评定管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

MySQL ------- 索引(B树B+树)

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;希望本文内容能帮到你&#xff01;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 目录 一&#xff1a;索引的特点 二&#xff1a;索引适用的场景 三&#xff1a;MySQL中索引操作 1&#xff1a;…

LTE SSS辅同步信号检测(相关法)

本文介绍一下SSS检测原理,本文采用联合检测算法,用复杂度来换取性能,适合工程上使用,SSS信号的产生往期已经介绍过了,这里就不介绍了。 1 SSS两个序列采用Interleaved结构而没有采用Localized集中式的原因是他比集中式可以获得更大的频率分集和干扰随机化效果。 2 根据3…

Python 从入门到实战22(类的定义、使用)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了面向对象简单介绍相关知识。今天我们将学习一…

828华为云征文 | 深度评测,华为云Flexus X实例在Sysbench性能测试中的亮眼表现

前言 本文章评测了华为云Flexus X实例在Sysbench性能测试中的亮眼表现。Flexus X凭借其新一代处理器和智能算力技术&#xff0c;在CPU、内存、磁盘I/O及网络性能上均展现出了卓越的能力。通过Sysbench的详尽测试&#xff0c;Flexus X实例在多核计算能力、内存吞吐量、磁盘响应速…

CSS传统布局方法(补充)——WEB开发系列37

开发技术不断演进&#xff0c;布局方式也经历了多个阶段的变革。从最初的基于表格布局到 CSS 的浮动布局&#xff0c;再到今天的弹性盒&#xff08;Flexbox&#xff09;与 CSS Grid 网格布局&#xff0c;每一种布局方式都有其独特的背景和解决特定问题的优势。 一、CSS Grid 出…

neo4j安装启动教程+对应的jdk配置

参考这位博主的视频教程&#xff1a;neo4j社区windows版下载 一、官网下载neo4j的安装包 &#xff08;1&#xff09;官网下载页面 &#xff08;2&#xff09;上一步 【download】之后&#xff0c;会自动下载&#xff0c;如果没有&#xff0c;点击【here】 这里可以看到一行字…

IDEA Project不显示/缺失文件

问题&#xff1a;侧边栏project 模式下缺少部分文件 先点close project 打开项目所在目录&#xff0c;删除目录下的.idea文件夹 重新open project打开这个项目即可解决

stm32单片机个人学习笔记4(GPIO输入)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

JavaDS —— 图

图的概念 图是由顶点集合以及顶点之间的关系组成的一种数据结构&#xff1a;G &#xff08;V&#xff0c;E&#xff09; 其中 V 表示的是顶点集合 &#xff1a; V { x | x 属于某个数据对象集} 是有穷非空集合 E 叫做边的集合 &#xff1a; E {(x, y) | x, y 属于 V} 或者 …

深度长文:揭开C/C++三目运算符的全部秘密,助你写出更优雅的代码(下)

在上篇文章中&#xff0c;我们深入探讨了三目运算符的基础语法、与if-else的对比以及使用中的常见误区。通过这些知识&#xff0c;你已经掌握了如何在代码中使用三目运算符来简化条件判断。 然而&#xff0c;三目运算符在C和C中的应用并不仅限于简单的条件选择。接下来&#x…