认识异常详解

news2024/11/24 17:26:49

1. 异常的定义:

在Java中,异常(Exception)是在程序执行过程中可能出现的错误或意外情况。异常可以分为两种类型:受检异常(Checked Exception)未受检异常(Unchecked Exception)

所谓异常,就是一个一个的类,他们之间存在着父子类关系,如下图所示:

2. 异常的分类: 

  1. 受检异常(Checked Exception)

    • 受检异常是指在编译时必须进行处理的异常。它们是 Exception 的子类(不包括 RuntimeException 和其子类),通常表示程序能够合理预料和处理的情况,如文件未找到、网络连接中断等。
    • 受检异常必须通过 try-catch 块或者在方法签名中使用 throws 关键字声明,否则编译器将报错。
  2. 未受检异常(Unchecked Exception)

    • 未受检异常也称为运行时异常(RuntimeException)及其子类。它们通常表示程序运行时出现的错误,如空指针异常(NullPointerException)、数组越界异常(ArrayIndexOutOfBoundsException)等。
    • 未受检异常不要求显式地捕获或者声明,因为它们通常是由程序逻辑错误引起的,应该在代码中避免。

 受检异常:

特点和处理方式

  1. 必须处理或声明

    • 受检异常必须在代码中显式处理,否则编译器将会报错。这是Java编译器强制执行的规定,以保证程序在可能出现问题的地方有预防措施。
  2. 常见的受检异常

    • IOException:处理输入输出流时可能抛出的异常,如文件未找到、文件读写错误等。
    • SQLException:操作数据库时可能抛出的异常。
    • ClassNotFoundException:试图加载类时找不到该类时抛出的异常。
    • FileNotFoundException:尝试打开一个不存在的文件时抛出的异常。
  3. 异常处理方式

    a. 使用 try-catch 块

try {
    // 可能抛出受检异常的代码块
    FileReader file = new FileReader("file.txt");
    // 其他可能抛出异常的操作
} catch (FileNotFoundException e) {
    // 处理异常的代码
    e.printStackTrace();
} catch (IOException e) {
    // 处理其他IO异常的代码
    e.printStackTrace();
}

 

  • 在 try 块中放置可能抛出异常的代码,每个 catch 块用于捕获不同类型的异常,并在捕获到异常后执行相应的处理逻辑。

b. 使用 throws 关键字抛出异常

  • 方法签名中使用 throws 关键字声明方法可能抛出的受检异常。这样做可以将异常向上层调用者传递,由调用者处理。
public void readFile() throws IOException, FileNotFoundException {
    FileReader file = new FileReader("file.txt");
    // 其他可能抛出异常的操作
}
    • 调用 readFile() 方法时,调用者必须要么在其内部使用 try-catch 块处理异常,要么在其方法签名中继续向上抛出异常。
  1. 适用场景

    • 当方法中有可能出现会影响程序正常运行的情况时,应该使用受检异常。这种异常通常要求程序员预见可能的问题,并在代码中进行相应的处理,以保证程序的稳定性和可靠性。
  2. 最佳实践

    • 在处理受检异常时,建议不仅仅是简单地打印堆栈信息,而是根据具体情况采取适当的措施,比如向用户报告错误、进行重试、回滚操作等,以便尽可能地恢复正常的程序执行状态。

未受检异常:

特点和处理方式

  1. 不需要显式处理或声明

    • Java编译器不会强制要求在代码中捕获或声明未受检异常,这使得程序员在处理逻辑上更加灵活,但也需要注意避免因未捕获的异常导致程序意外终止。
  2. 常见的未受检异常

    • NullPointerException:当引用为空(null)时尝试调用其方法或访问其属性时抛出。
    • ArrayIndexOutOfBoundsException:尝试访问数组中不存在的索引位置时抛出。
    • ArithmeticException:数学运算异常,如除以零。
    • IllegalArgumentException:方法接收到非法参数时抛出。
    • ClassCastException:类型转换异常,在类型转换时发生类型不兼容时抛出。
  3. 异常处理方式

    • 尽管未受检异常不要求强制处理,但好的编程实践是在可能引发这些异常的地方进行适当的逻辑检查,以避免程序出现异常状态。
    • 如果未捕获的未受检异常发生,通常会导致程序异常终止,并打印异常堆栈信息,这可以帮助定位问题所在。
  4. 适用场景

    • 未受检异常通常表示程序员在代码逻辑中出现了错误或者未能预料到的情况。例如,当方法要求传入的参数为非空时却接收到了空值,可以抛出 NullPointerException。这种异常通常需要通过改进代码逻辑来避免,而不是依赖于异常处理机制。
  5. 最佳实践

    • 在编写代码时,应该注意对可能导致未受检异常的情况进行检查和预防,尽量避免程序运行时因为这类异常而意外终止。
    • 对于可能引发未受检异常的方法,可以通过文档、注释或者断言等手段来说明其预期的使用条件,以便其他开发人员正确使用。

3. 异常的处理:

捕获异常(try-catch)

  • 使用 try 块包裹可能会引发异常的代码,然后通过 catch 块捕获特定类型的异常并处理它们。
try {
    // 可能抛出异常的代码块
    int result = 10 / 0; // 这里会抛出 ArithmeticException
} catch (ArithmeticException e) {
    // 处理算术异常的代码
    System.out.println("除数不能为零");
} catch (Exception e) {
    // 捕获其他类型的异常
    e.printStackTrace();
}
  • try 块中的代码在执行时,如果抛出了 ArithmeticException 异常(例如除以零),程序会跳到对应的 catch 块中执行处理逻辑。

 

抛出异常(throw)

  • 当方法内部无法处理某些异常情况时,可以使用 throw 关键字显式地抛出异常对象,将异常传递给调用者处理。
public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException("余额不足");
    }
    // 执行取款操作
    balance -= amount;
}
  • 在上述例子中,如果取款金额大于账户余额,则抛出自定义的 InsufficientFundsException 异常。

  • 使用 finally 块

    FileInputStream file = null;
    try {
        file = new FileInputStream("file.txt");
        // 读取文件
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        // 关闭文件流,确保资源得到释放
        if (file != null) {
            try {
                file.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

  • finally 块用于执行无论是否发生异常都需要执行的代码,比如资源释放操作(如关闭文件、数据库连接等)。

使用 try-with-resources(Java 7+):

  • 当需要处理的资源实现了 AutoCloseable 或 Closeable 接口时,可以使用 try-with-resources 语句自动关闭资源。
try (FileInputStream file = new FileInputStream("file.txt")) {
    // 读取文件
} catch (IOException e) {
    e.printStackTrace();
}
  • 在 try 后面的括号中声明资源,程序结束时会自动调用其 close() 方法,无需手动关闭资源。

异常处理的最佳实践

  • 选择合适的异常处理方式:根据具体情况选择 try-catchthrowfinally 或 try-with-resources 等方式。
  • 准确捕获异常:捕获尽可能具体的异常类型,避免过于宽泛的 catch (Exception e) 形式。
  • 避免捕获过多:尽可能在能够预见和处理异常的地方捕获和处理,而不是在整个应用程序的最高层捕获所有异常。
  • 异常信息的处理:合理利用异常信息提供的堆栈信息,帮助调试和定位问题。
  • 保持代码清晰:异常处理应与正常逻辑分开,保持代码的清晰和可读性。

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

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

相关文章

C9联盟是什么?

九校联盟(C9 League),简称C9联盟,是中国首个顶尖大学间的高校联盟,于2009年10月正式启动。 其成员都是国家首批“985工程”重点建设的一流大学,包括北京大学、清华大学、哈尔滨工业大学、复旦大学、上海交通…

水仙花数算法

一、水仙花的传说 希腊神话故事 传说希腊神话里,美少年纳西索斯(Narcissus)是希腊最俊美的男子,无数的少女对他一见倾心,可他却自负地拒绝了所有的人。这当中包括美丽的山中仙女伊可(Echo)。伊可…

(南京观海微电子)——MOS管原理及应用区别

MOS管: 全称为金属氧化物半导体场效应管(Metal Oxide Semiconductor Field Effect Transistor),也被称为MOSFET(Metal-Oxide-Semiconductor Field-Effect Transistor)。它是一种半导体器件,常用…

Vulkan 学习(1)---- Vulkan 基本概念和发展历史

目录 Vulkan及其演化史Vulkan 基本概念基本术语 Vulkan 的原理Vulkan应用程序Vulkan的编程模型硬件初始化窗口展示表面资源设置流水线设置描述符和描述符缓冲池基于SPIR-V的着色器流水线管理指令的记录队列的提交 Vulkan及其演化史 目前主流的图形渲染API有OpenGL、OpenGL ES、…

Sequelize 操作 MySQL 数据库

安装 npm install --save sequelize安装驱动程序: npm install --save mysql2连接到数据库 要连接到数据库,必须创建一个 Sequelize 实例. 这可以通过将连接参数分别传递到 Sequelize 构造函数或通过传递一个连接 URI 来完成: const {Sequelize} re…

【Linux系统编程】文件系统

介绍: 文件系统是操作系统中负责管理和存储文件信息的软件结构,它组织和管理磁盘上的文件和目录,并定义了文件的存储结构。 Linux文件系统采用树状结构,只有一个根目录(用“/”表示),其中含有下…

C++ 函数高级——函数的默认参数

函数默认参数 在C中,函数的形参列表中的形参是可以有默认值的 语法:返回值类型 函数名 (参数 默认值){ } 示例: 正确代码: 运行结果:

黑马|最新AI+若依 |初识项目

本章主要内容是: 1.快速搭建了若依前后端项目在本地 2.实现了单表的增删改查快速生成 文章目录 介绍1.若依介绍2.若依的不同版本3.项目运行环境 初始化前后端项目1.下载若依项目2.初始化后端a.把表导入到数据库中b.更改application.yml文件 3.初始化前端a.安装依赖…

java集合(2)

目录 一. Map接口下的实现类 1. HashMap 1.1 HashMap常用方法 2. TreeMap 2.1 TreeMap常用方法 3. Hashtable 3.1 Hashtable常用方法 4.Map集合的遍历 4.1 根据键找值 4.2 利用map中的entrySet()方法 二.Collections类 1.Collections类中的常用方法 三. 泛型 1. 为什…

大连外贸建站公司wordpress主题模板

Robonaut萝卜纳特WP外贸站模板 适合用于工业机器人公司出口做外贸搭建公司官方网站使用的WordPress模板。 https://www.jianzhanpress.com/?p7091 优衣裳WordPress外贸建站模板 简洁的wordpress外贸独立站模板,适合服装、衣服、制衣外贸公司搭建公司官方网站使用…

shark云原生-日志体系-filebeat高级配置(适用于生产)-更新中

文章目录 1. filebeat.inputs 静态日志收集器2. filebeat.autodiscover 自动发现2.1. autodiscover 和 inputs2.2. 如何配置生效2.3. Providers 提供者2.4. Providers kubernetes2.5. 配置 templates2.5.1. kubernetes 自动发现事件中的变量字段2.5.2 配置 templates 2.6. 基于…

人工智能系列-Pandas基础

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” Pandas简介 Pandas是Python语言的拓展程序库,用于数据分析。 Pandas是一个开放源码,BSD许可的库,提供高性能,易于使用的数据结…

vuepress创建步骤

背景 记录vuepress配置步骤,以便下次使用快速上手。 读此文章之前默认您已经学会了创建vuepress项目。vuepres快速开始 最终成品 doc.jeecgflow.com 配置步骤 创建.vuepress 目录。 你的文档目录下创建一个 .vuepress 目录。 创建.vuepress/config.js module.e…

【IMU】 确定性误差与IMU_TK标定原理

1、确定性误差 MEMS IMU确定性误差模型 K 为比例因子误差 误差来源:器件的输出往往为脉冲值或模数转换得到的值,需要乘以一个刻度系数才能转换成角速度或加速度值,若该系数不准,便存在刻度系数误差。 T 为交轴耦合误差 误差来源:如下图,b坐标系是正交的imu坐标系,s坐标系的三…

spring-ai 下载不了依赖spring-ai-openai-spring-boot-starter

第1坑:配置第三方仓库不生效, 提示在阿里云仓库没有找到 spring-ai-openai-spring-boot-starter 第2坑:升级jdk17后,springboot项目启动报错 Internal error (java.lang.reflect.InaccessibleObjectException): Unable to make pr…

第10章:网络与信息安全

目录 第10章:网络与信息安全 网络概述 计算机网络概念 计算机网络的分类 网络的拓扑结构 ISO/OSI网络体系结构 网络互联硬件 物理层互联设备 数据链路层互联设备 网络层互联设备 应用层互联设备 网络的协议与标准 网络标准 TCP/IP协议族 网络接口层协…

【若依前后端分离】通过输入用户编号自动带出部门名称(部门树)

一、部门树 使用 <treeselect v-model"form.deptId" :options"deptOptions" :show-count"true" placeholder"请选择归属部门"/> <el-col :span"12"><el-form-item label"归属部门" prop"dept…

C++ 什么是虚函数?什么是纯虚函数,以及区别?(通俗易懂)

&#x1f4da; 当谈到虚函数时&#xff0c;通常是指在面向对象编程中的一种机制&#xff0c;它允许在派生类中重写基类的函数&#xff0c;并且能够通过基类指针或引用调用派生类中的函数。 目录 前言 &#x1f525; 虚函数 &#x1f525; 纯虚函数 &#x1f525; 两者区别…

IntelliJ IDEA教育版在Windows电脑中的下载、安装方法

本文介绍IntelliJ IDEA软件Community&#xff08;社区版&#xff09;在Windows操作系统中的下载、安装、运行与使用方法。 IntelliJ IDEA软件是一款由JetBrains公司开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于Java语言的开发&#xff0c;但同时也支持其…

win7系统快速安装python

下载安装包 建议选择python3.8左右的&#xff0c;我下载的是3.7.8&#xff0c;最新版本的pythonwin7可能不支持 python网址 下拉寻找 安装python 1.双击安装包 更换完地址选择安装(install) 安装完成后点击close即可 测试是否安装成功 1.winr快捷键打开黑窗口输入cmd …