从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java数据类型

    • Java 多版本配置
    • 面向对象

    • Java核心类

    • IO

    • Java与时间

    • 异常处理

      • 什么是异常
        • 异常概述
        • Java 中的异常
        • 异常的种类
        • 什么异常应该被处理
        • 小结
      • 捕获和抛出异常
      • 深入异常
      • 自定义异常
      • 空指针异常
      • return 和 finally 谁先执行
    • 哈希和加密算法

    • Java8新特性

    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • 异常处理
2023-02-13
目录

什么是异常

# 什么是异常

程序运行的时候,经常会发生各种错误。例如,当你尝试把 0 作为除数,Java 程序是处理的不了结果的,因为违反了运算规则,出现异常。本章我们讨论如何在 Java 程序中处理各种异常情况。

# 异常概述

异常发生的原因很多,有些是用户造成的(例如输入除数的时候,输入了 0),或者读取某个文件的时候,文件已经被删除了,这样的情况下,Java 程序都不能正常得到结果,会发生错误。

还有一些错误是随机出现,并且永远不可能避免的。比如:

  • 网络突然断了,连接不到远程服务器;
  • 内存耗尽,程序崩溃了;
  • 用户点“打印”,但根本没有打印机;
  • ……

所以,一个健壮的程序必须处理各种各样的错误。

所谓错误,就是程序调用某个函数的时候,如果失败了,就表示出错。而如何知道调用失败的原因呢?我们可以约定错误码(每个错误码对应一个具体的错误信息)。

例如,处理一个文件,如果返回 0,表示成功,返回其他整数,表示约定的错误码:

int code = processFile("C:\\test.txt");
if (code == 0) {
    // ok:
} else {
    // error:
    switch (code) {
    case 1:
        // file not found:
    case 2:
        // no read permission:
    default:
        // unknown error:
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

因为使用 int 类型的错误码,想要处理就非常麻烦。这种方式常见于底层 C 函数。

# Java 中的异常

如果全靠自己手工处理异常,得增加很多工作量,并且各个项目之间的异常处理都不一样,没有一个标准。

为此,Java 内置了一套异常处理机制,总是使用异常来表示错误,这些错误会作为异常抛出。

异常是一种 class,它本身带有类型信息,表明阻止正常进行程序的错误或情况,如果异常没有被处理,程序就会非正常终止。

异常的继承关系如下:

                     ┌───────────┐
                     │  Object   │
                     └───────────┘
                           ▲
                           │
                     ┌───────────┐
                     │ Throwable │
                     └───────────┘
                           ▲
                 ┌─────────┴─────────┐
                 │                   │
           ┌───────────┐       ┌───────────┐
           │   Error   │       │ Exception │
           └───────────┘       └───────────┘
                 ▲                   ▲
         ┌───────┘              ┌────┴──────────┐
         │                      │               │
┌─────────────────┐    ┌─────────────────┐┌───────────┐
│OutOfMemoryError │... │RuntimeException ││IOException│...
└─────────────────┘    └─────────────────┘└───────────┘
                                ▲
                    ┌───────────┴─────────────┐
                    │                         │
         ┌─────────────────────┐ ┌─────────────────────────┐
         │NullPointerException │ │IllegalArgumentException │...
         └─────────────────────┘ └─────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 异常的种类

为了方便,我们可以人为地将异常分为三种类型:系统错误 Error、运行时异常 RuntimeException 和 非运行时异常 Exception。

# Error

系统错误( system error)是由 Java 虚拟机抛出的,用 Error 类表示。

Error 类描述的是内部系统错误,这样的错误很少发生。如果发生,除了通知用户以及尽量稳妥地终止程序外,几乎什么也不能做,例如:

  • OutOfMemoryError:内存耗尽
  • NoClassDefFoundError:无法加载某个 Class
  • StackOverflowError:栈溢出
  • LinkageError:一个类对另一个类有某种依赖性,但是在编译前者后,后者进行了修改,变得不兼容
  • virtualMachineError:Java 虚拟机崩溃,或者运行所必需的资源已经耗尽

# RuntimeException

运行时异常描述的是程序设计错误,通常是在程序运行时,由 Java 虚拟机抛出的,例如:

  • NullPointerException:对某个 null 的对象调用方法或字段。例如变量还未初始化就使用
  • IndexOutOfBoundsException:数组索引越界
  • InputMismatchException:比如你希望用户输入整数,但是用户输入了小数,在转换为数字的时候就会有异常。
  • ArithmeticException:一个整数除以 0。注意,浮点数的算术运算不抛出异常,因为浮点数不是很精确,难以真正的表示 0。
  • IllegalArgumentException:传递给方法的参数非法或不合适

# Exception

这里指的 Exception 不包含 RuntimeException,它描述的是由程序和外部环境所引起的错误,例如:

  • ClassNotFoundException:试图使用一个不存在的类。例如,如果试图使用命令 java 来运行一个不存在的类,或者程序要调用三个类文件而只能找到两个,都会发生这种异常
  • IOException:同输入/输出相关的操作,例如,无效的输入、读文件时超过文件尾、打开一个不存在的文件等。IOException 的子类的例子有 InterruptedIOException. EOFException(EOF 是 End of File 的缩写)和 FileNotFoundException

# 什么异常应该被处理

  • Error、RuntimeException,以及他们的子类都是免检异常(unchecked Exception),也就是可以不处理的
  • 除了免检异常,其他异常都是必检异常(checked Exception),必须使用 try-catch 块处理,或者在方法头进行声明(下一节会讲)。

大部分情况下,免检异常(RuntimeException 及其子类)都是由于逻辑错误造成的,例如:

  • NullPointerException:对某个 null 的对象调用方法或字段。例如变量还未初始化就使用,这是逻辑错误;
  • IndexOutOfBoundsException:数组索引越界,例如一个数组只有 10 个元素,但程序访问其第 11 个元素,这也是代码有问题;
  • ArithmeticException:一个整数除以 0,基本的四则运算规则都违背了,应该判断除数是否为 0;
  • …………

综上,免检异常可能在程序的任何一个地方出现。为避免过多地使用异常处理代码, Java 语言不强制要求编写代码捕获或声明免检异常。

但是必检异常,通常就不是程序问题了,而是外部的问题,例如:

  • IOException:要操作的文件不见了,或者没权限等等
  • SocketException:读取网络失败,比如网络突然断了掉线了

必检异常,通常是我们可以处理的。例如网络异常,我们可以捕捉到异常,然后告知用户是网络异常;或者 IOException,比如你在重命名一个正在打开的文件,也会有提示。

注意:编译器对 RuntimeException 及其子类不做强制捕获要求,但不是指应用程序本身不应该捕获并处理 RuntimeException。是否需要捕获,具体问题具体分析。

# 小结

本文我们介绍了如下内容:

  • 什么是异常
  • Java 中的异常体系
  • 异常的分类
  • 什么异常应该被处理

异常也是 Java 中很基本的概念,并且在工作中会经常需要和处理异常,请读者好好掌握。

上次更新: 2024/10/1 16:58:10
Java 新旧时间 API 转换
捕获和抛出异常

← Java 新旧时间 API 转换 捕获和抛出异常→

最近更新
01
吐槽一下《僵尸校园》
05-15
02
2025 年 4 月记
04-30
03
山西大同 “订婚强奸案” 将会给整个社会带来的影响有多严重? - 知乎 转载
04-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式