认识 Java 中的异常 看这篇

2023-11-02

目录

1. 初始异常

2. 防御式编程

3. 异常的基本用法

3.1 基本语法

3.2 为什么要处理异常

3.3 关于异常的处理方式

3.4 异常处理流程

3.5 捕获异常的注意点

3.6 抛出异常

3.7 关于finally

4. Java 异常体系

4.1 Java 内置的异常类之间的继承关系图

4.2 受查异常和非受查异常的区别

5. 自定义异常类


1. 初始异常

异常指的是程序在运行时出现错误时通知调用者的一种机制。

“运行时”指的是程序已经编译通过得到 class 文件了,再由 JVM 执行过程中出现的错误。而有些错误是编译过程中就会出错,这是“编译期”出错。

2. 防御式编程

错误在代码中是客观存在的,要让程序出现问题的时候及时通知程序员,有两种方式。

  • LBYL: Look Before You Leap. 在操作之前就做充分的检查。
  • EAFP: It's Easier to Ask Forgiveness than Permission. "事后获取原谅比事前获取许可更容易". 也就是先操作, 遇到问题再处理。异常的核心就是 EAFP.

3. 异常的基本用法

3.1 基本语法

try{
    有可能出现异常的语句 ;
} catch (异常类型 异常对象) {
    ... 
} finally {
    异常的出口
}

其中:

try 代码块中放的是可能出现异常的代码。
catch 代码块中放的是出现异常后的处理行为。
finally 代码块中的代码用于处理善后工作, 会在最后执行。
其中 catch 和 finally 都可以根据情况选择加或者不加。

3.2 为什么要处理异常

程序中如果一旦出现异常,不处理异常,程序就终止了,异常之后的代码段就不会执行。

比如:

但如果进行异常处理,一旦 try 中出现异常,那么 try 代码块中的程序就不会继续执行,而是交给 catch 中的代码来执行。catch 中的代码执行完毕后会继续执行,程序不会停止。这样就有利于程序的执行效率。 

 关于 "调用栈"
方法之间是存在相互调用关系的, 这种调用关系我们可以用 "调用栈" 来描述。 在 JVM 中有一块内存空间称为 "虚拟机栈" 专门存储方法之间的调用关系。当代码中出现异常的时候, 我们就可以使用 e.printStackTrace(); 的方式查看出现异常代码的调用栈。

3.3 关于异常的处理方式

异常的种类有很多, 我们要根据不同的业务场景来决定。
1. 对于比较严重的问题(例如和算钱相关的场景), 应该让程序直接崩溃, 防止造成更严重的后果。
2. 对于不太严重的问题(大多数场景), 可以记录错误日志, 并通过监控报警程序及时通知程序员。
3. 对于可能会恢复的问题(和网络相关的场景), 可以尝试进行重试。
在我们当前的代码中采取的是经过简化的第二种方式。我们记录的错误日志是出现异常的方法调用信息, 能很快速的让我们找到出现异常的位置.。以后在实际工作中我们会采取更完备的方式来记录异常信息。

3.4 异常处理流程

1. 程序先执行 try 中的代码。
2. 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配。
3. 如果找到匹配的异常类型, 就会执行 catch 中的代码。
4. 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者。
5. 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行)。
6. 如果上层调用者也没有处理的了异常, 就继续向上传递。一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止。

3.5 捕获异常的注意点

1. 一段代码可能会抛出多种不同的异常,不同的异常有不同的处理方式,因此可以搭配有多个 catch 代码块;

2. 也可以用一个 catch 捕获所有异常(这种方式不推荐);

Exception 类是所有异常类的父类,因此可以用这个类型表示捕捉所有异常,如上面代码出现的NullPointerException 异常都是 Exception 的子类。 

3. 无论是否存在异常,finally 中的代码一定会执行的,保证最终一定会执行到 Scanner 的 close 方法。  

4.  如果本方法中没有合适的处理异常的方式, 就会沿着调用栈向上传递。

 如果 func 方法中没有合适的处理异常方式,就会沿着调用栈向上传递到 main 方法中,如果 main 方法中也没有合适的处理异常方式,就会一直向上传递,如果向上一直传递都没有合适的方法处理异常, 最终就会交给 JVM 处理, 程序就会异常终止(和我们最开始未使用 try catch 时是一样的)。

3.6 抛出异常

throw 和 throws 的区别

throw:用在方法内部,手动抛出异常,必须要人工产生一个异常对象。

throws:用在方法声明,表示当前方法可能会出现的异常并且不处理继续向调用者抛出。

3.7 关于finally

finally 执行的时机是在方法返回之前( try 或者 catch 中如果有 return 会在这个 return 之前执行 finally)。但是如果 finally 中也存在 return 语句, 那么就会执行 finally 中的 return, 会覆盖掉 try 或 catch 中的 return。一般不建议在 finally 中写 return。

4. Java 异常体系

4.1 Java 内置的异常类之间的继承关系图

  • 顶层类 Throwable 派生出两个重要的子类, Error 和 Exception
  • 其中 Error 指的是 Java 运行时内部错误和资源耗尽错误。比如栈溢出 StackOverFlowError 、内存溢出 OutofMemoryError 等错误。应用程序不抛出此类异常。这种内部错误一旦出现,除了告知用户并使程序终止之外, 再无能无力。
  • Exception 是我们程序猿所使用的异常类的父类。其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类 NullPointerException , IndexOutOfBoundsException 等。这种称为非受查异常。

Java 语言将 Error 类、RuntimeException 类及其子类的所有异常称为非受查异常,其他的类 IOException 类及其子类、ClassNotFoundException 类、CloneNotSupportedException 类都是受查异常

4.2 受查异常和非受查异常的区别

受查异常:程序必须显示 try ... catch 异常处理 或者 throws 向上抛出。

非受查异常:属于非受查异常可以不用显示处理该异常。

5. 自定义异常类

当开发中遇到某些与业务相关的出错情况时,需要自定义异常。

比如用户登录功能,此时处理用户名和密码错误的时候就可能抛出两种异常,基于已有的异常类 Exception 进行继承,创建出和业务相关的异常类。

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

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

此时相关业务代码就是:

/**
 * 自定义异常
 */
class UserError extends Exception {
    public UserError(String message) {
        super(message);
    }
}

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

public class Demo6 {
    private static String userName = "admin";
    private static String password = "123456";
    public static void main(String[] args) {
        try {
            login("admin", "12456");
        } catch (UserError userError) {
            userError.printStackTrace();
        } catch (PasswordError passwordError) {
            passwordError.printStackTrace();
        }
    }

    public static void login(String userName, String password) throws UserError,
            PasswordError {
        if (!Demo6.userName.equals(userName)) {
            throw new UserError("用户名错误");
        }
        if (!Demo6.password.equals(password)) {
            throw new PasswordError("密码错误");
        }
        System.out.println("登陆成功");
    }
}

 如果密码或者用户名错误就会抛出错误:

 

自定义异常通常会继承自 Exception 或者 RuntimeException,继承自 Exception 的异常默认是受查异常,继承自 RuntimeException 的异常默认是非受查异常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

认识 Java 中的异常 看这篇 的相关文章

  • Spring应用中Eureka健康检查的问题

    我正在开发一个基于 Spring 的应用程序 其中包含多个微服务 我的一个微服务充当尤里卡服务器 到目前为止一切正常 在我所有其他微服务中 用 EnableEurekaClient 我想启用这样的健康检查 应用程序 yml eureka c
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • Pig Udf 显示结果

    我是 Pig 的新手 我用 Java 编写了一个 udf 并且包含了一个 System out println 其中的声明 我必须知道在 Pig 中运行时该语句在哪里打印 假设你的UDF 扩展了 EvalFunc 您可以使用从返回的 Log
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 将 MOXy 设置为 JAXB 提供程序,而在同一包中没有属性文件

    我正在尝试使用 MOXy 作为我的 JAXB 提供程序 以便将内容编组 解组到 XML JSON 中 我创建了 jaxb properties 文件 内容如下 javax xml bind context factory org eclip
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • 内部类的构造函数引用在运行时失败并出现VerifyError

    我正在使用 lambda 为内部类构造函数创建供应商ctx gt new SpectatorSwitcher ctx IntelliJ建议我将其更改为SpectatorSwitcher new反而 SpectatorSwitcher 是我正
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • JPA学习笔记 - 关联关系

    OneToMany 指定 1对多 的映射关系 可通过fetch的属性设置加载方式 JoinColmn 指定外键的列名 外键存在于 多 的一方表中 单向 n 1 先保存n的一端时 会多出update语句 因为插入n端时并未知道外键的值 插入1
  • java8 新特性stream流学习

    简介 java 8 API添加了一个新的抽象称为流Stream 可以让你以一种声明的方式处理数据 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象 Stream API可以
  • 离散数学-二元关系

    目录 序偶与有序n元组 集合的笛卡尔积 关系的基本概念 关系的表示方法 特殊关系 关系的性质 自反性 反自反性 对称性 反对称性 传递性 关系的复合运算 1 基本概念 2 计算方法 2 1 有向图法 2 2 枚举法 2 3 谓词公式法 3
  • 微信小程序实现文字随机颜色

    1 实现效果 2 实现思路 从颜色列表中随机取一个颜色 赋值给数组的每一项 Math floor Math random colorArr length 3 实现代码
  • python爬虫需要哪些基础知识-【PYTHON】【爬虫】关于python爬虫的一些基础知识

    基础知识 HTTP协议 我们浏览网页的浏览器和手机应用客户端与服务器通信几乎都是基于HTTP协议 而爬虫可以看作是一个另类的客户端 它把自己伪装成浏览器或者手机应用客户端 按照自己的逻辑贪婪的向服务器索取数据 如何向服务器索取数据 所以了解
  • android开启安装权限管理,Android6.0权限——安装时默认开启app全部权限

    1 默认开启app全部权限 Android6 0之后推出动态申请权限 所有敏感权限默认都是没有开启的状态 这两天偶然间看到其他app安装后所有权限 包括敏感权限 默认都是开启的状态 6 0之后敏感权限都需要申请的 怎么可能跨过用户的 好奇心
  • 5种常用格式的数据输出,手把手教你用Pandas实现

    导读 任何原始格式的数据载入DataFrame后 都可以使用类似DataFrame to csv 的方法输出到相应格式的文件或者目标系统里 本文将介绍一些常用的数据输出目标格式 01 CSV DataFrame to csv方法可以将Dat
  • webcomponents安装了没有用_Web Components基本概念及实例教程

    谷歌公司由于掌握了 Chrome 浏览器 一直在推动浏览器的原生组件 即 Web Components API 相比第三方框架 原生组件简单直接 符合直觉 不用加载任何外部模块 代码量小 目前 它还在不断发展 但已经可用于生产环境 基本概念
  • 如何使用 Javadoc 工具生成文档

    Javadoc 是一个由 Java 语言编写的工具 用于从 Java 代码中提取注释并生成 HTML 格式的文档 以下是使用 Javadoc 工具生成文档的一般步骤 编写代码并添加注释 在你的 Java 代码中添加注释是生成文档的关键 Ja
  • pycharm连接ssh debug卡住 解决方案

    修改dataloder中的worker 修改pycharm setting
  • 2021经典优秀计算机单片机毕业设计题目

    可追溯农产品电商管理系统的设计与实现 农产品用户商城系统设计与实现 基于OpenGL的全局光照算法的设计与实现 分布式存储系统分析与设计 基于机器学习的数据库融合技术研究 基于知识图谱的对话系统设计与实现 具有日志的虚拟WEB攻防系统设计与
  • 蓝桥杯省赛模拟题 信号覆盖

    题目大意 小蓝负责一块区域的信号塔安装 整块区域是一个长方形区域 建立坐标轴后 西南角坐标为 0 0 0 0 0 0 东南角坐标为
  • 计算机恢复语言文件格式,txt文件乱码怎么恢复正常

    txt是最常见的一种文件格式 几乎所有的文本编辑器都可以打开和编辑TXT文件 不过有网友在打开该文件时却遇到了乱码的情况 这是怎么回事呢 我们该如何操作才能使之恢复正常呢 用户可能不是很了解 所以今天本文为大家分享的就是电脑打开txt文档乱
  • ChatGPT + Stable Diffusion + 百度AI + MoviePy 实现文字生成视频,小说转视频,自媒体神器!(二)

    ChatGPT Stable Diffusion 百度AI MoviePy 实现文字生成视频 小说转视频 自媒体神器 二 前言 最近大模型频出 但是对于我们普通人来说 如何使用这些AI工具来辅助我们的工作呢 或者参与进入我们的生活 就着现在
  • Effective STL

    外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img qcpwxQhi 1585901574462 C Users w00448203 AppData Roaming Typora typora user images
  • WPF DataGrid添加自定义操作列

    WPF页面有个DataGrid列表 需要为在最后加一列操作列从而实现对每一行记录的自定义操作 页面xaml内容 样式组件引用的是metro mahapps
  • 一次不规范HTTP请求引发的nginx响应400问题分析与解决

    背景 最近分析数据偶然发现nginx log中有一批用户所有的HTTP POST log上报请求均返回400 没有任何200成功记录 由于只占整体请求的不到0 5 所以之前也一直没有触发监控报警 而且很奇怪的是只对于log上报的POST接口
  • 动态时间规整算法(dynamic time warping)

    动态时间规整 DT W 动态 时间 规整 DTW dynamic time warping 曾经是语音识 别的一种主流方法 其 思想是 由于 语音信号是一种具有相当大随机性的信 号 即使相同说话者对相同的词 每一次发音的结果 都是不同的 也
  • 游戏开发unity插件MessagePack:基本介绍(附带messagepack、protobuf、json的压缩的大小和性能对比)

    参考 https www cnblogs com Leo wl p 8143259 html https github com neuecc MessagePack CSharp 官方github https github com neue
  • 认识 Java 中的异常 看这篇

    目录 1 初始异常 2 防御式编程 3 异常的基本用法 3 1 基本语法 3 2 为什么要处理异常 3 3 关于异常的处理方式 3 4 异常处理流程 3 5 捕获异常的注意点 3 6 抛出异常 3 7 关于finally 4 Java 异常