9.异常

news2024/9/17 7:16:11

文章目录

  • 9.1 Java 异常类层次结构图
  • 9.2 Throwable 类常用方法
  • 9.3 try-catch-finally
  • 9.4使用 `try-with-resources` 来代替`try-catch-finally`

9.1 Java 异常类层次结构图

在这里插入图片描述
在这里插入图片描述
在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类 Exception(异常)和 Error(错误)。Exception 能被程序本身处理(try-catch), Error 是无法处理的(只能尽量避免)。

ExceptionError 二者都是 Java 异常处理的重要子类,各自都包含大量子类。

  • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 受检查异常(必须处理) 和 不受检查异常(可以不处理)。
  • ErrorError 属于程序无法处理的错误 ,我们没办法通过 catch 来进行捕获 。例如,Java 虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。

受检查异常

Java 代码在编译过程中,如果受检查异常没有被 catch/throw 处理的话,就没办法通过编译 。比如下面这段 IO 操作的代码。

在这里插入图片描述
除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常 。常见的受检查异常有: IO 相关的异常、ClassNotFoundExceptionSQLException…。

不受检查异常

Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。

RuntimeException 及其子类都统称为非受检查异常,例如:NullPointExceptionNumberFormatException(字符串转换为数字)、ArrayIndexOutOfBoundsException(数组越界)、ClassCastException(类型转换错误)、ArithmeticException(算术错误)等。

9.2 Throwable 类常用方法

  • public string getMessage():返回异常发生时的简要描述
  • public string toString():返回异常发生时的详细信息
  • public string getLocalizedMessage():返回异常对象的本地化信息。使用 Throwable 的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
  • public void printStackTrace():在控制台上打印 Throwable 对象封装的异常信息

9.3 try-catch-finally

  • try块: 用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
  • catch块: 用于处理 try 捕获到的异常。
  • finally 块: 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

在以下 3 种特殊情况下,finally 块不会被执行:

  1. tryfinally 块中用了 System.exit(int)退出程序。但是,如果 System.exit(int) 在异常语句之后,finally 还是会被执行
  2. 程序所在的线程死亡。
  3. 关闭 CPU。

下面这部分内容来自 issue:https://github.com/Snailclimb/JavaGuide/issues/190。
注意: 当 try 语句和 finally 语句中都有 return 语句时,在方法返回之前,finally 语句的内容将被执行,并且 finally 语句的返回值将会覆盖原始的返回值。如下:

public class Test {
    public static int f(int value) {
        try {
            return value * value;
        } finally {
            if (value == 2) {
                return 0;
            }
        }
    }
}

如果调用 f(2),返回值将是 0,因为 finally 语句的返回值覆盖了 try 语句块的返回值。

9.4使用 try-with-resources 来代替try-catch-finally

  1. 适用范围(资源的定义): 任何实现 java.lang.AutoCloseable或者 java.io.Closeable 的对象
  2. 关闭资源和 final 的执行顺序:try-with-resources 语句中,任何 catch 或 finally 块在声明的资源关闭后运行

《Effecitve Java》中明确指出:

面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。

Java 中类似于InputStreamOutputStreamScannerPrintWriter等的资源都需要我们调用close()方法来手动关闭,一般情况下我们都是通过try-catch-finally语句来实现这个需求,如下:

//读取文本文件的内容
        Scanner scanner = null;
        try {
            scanner = new Scanner(new File("D://read.txt"));
            while (scanner.hasNext()) {
                System.out.println(scanner.nextLine());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }

使用 Java 7 之后的 try-with-resources 语句改造上面的代码:

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

当然多个资源需要关闭的时候,使用 try-with-resources 实现起来也非常简单,如果你还是用try-catch-finally可能会带来很多问题。

通过使用分号分隔,可以在try-with-resources块中声明多个资源。

try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));
             BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {
            int b;
            while ((b = bin.read()) != -1) {
                bout.write(b);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }

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

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

相关文章

CentOS安装Postgresql

PG基本安装步骤 安装postgresql: sudo yum install postgresql-server初始化数据库:安装完毕后,需要初始化数据库并创建初始用户: sudo postgresql-setup initdb启动和停止服务: sudo systemctl start postgresql sudo…

06微服务间的通信方式

一句话导读 微服务设计的一个挑战就是服务间的通信问题,服务间通信理论上可以归结为进程间通信,进程可以是同一个机器上的,也可以是不同机器的。服务可以使用同步请求响应机制通信,也可以使用异步的基于消息中间件间的通信机制。同…

【TS第三讲】完善TS开发环境

文章目录 🌟 写在前面🌟 ts-node🌟 nodemon🌟 nodemon文件类型🌟 nodemon文件范围🌟 写在最后 🌟 写在前面 🔥探索TypeScript世界,驭Vue3Ts潮流,开启前端之旅…

【Ubuntu】简化反向代理和个性化标签页体验

本文将介绍如何使用Docker部署Nginx Proxy Manager和OneNav,两个功能强大且易用的工具。Nginx Proxy Manager用于简化和管理Nginx反向代理服务器的配置,而OneNav则提供个性化的新标签页体验和导航功能。通过本文的指导,您将学习如何安装和配置…

【打印整数二进制的奇数位和偶数位】

打印整数二进制的奇数位和偶数位 1.题目 获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列 2.题目分析 打印一个整数的二进制位中的偶数位和奇数位,可以对整数进行移位操作,再将移位的二进制位与1进行&操作。 按位&a…

HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制概述

ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。 在声明式描述语句中开发者除了使用系统组件外,还可以使用渲染控制语句来辅助UI的构建,这些渲染控制语句包括控制组件是否显示的条件渲染语句,基于数组数…

Rocky Linux更换为国内源

Rocky Linux提供的可供切换的源列表:Mirrors - Mirror Manager 其中以 COUNTRY 列为 CN 的是国内源。 选择其中一个Rocky Linux 源使用帮助 — USTC Mirror Help 文档 操作前请做好备份 对于 Rocky Linux 8,使用以下命令替换默认的配置 sed -e s|^mirr…

Java用方法实现登录名和密码的校验

Java用方法实现登录名和密码的校验 需求分析代码实现小结Time 需求分析 系统正确的登录名和密码是:学习/123,请在控制台开发一个登录界面,接收用户输入的登录名和密码,判断用户是否登录成功,登录成功后展示:“欢迎进入系统!”&…

一文5000字详解Python中PO模式的设计与实现

在使用 Python 进行编码的时候,会使用自身自带的编码设计格式,比如说最常见的单例模式等。本文将为大家介绍PageObject自动化设计模式(PO模式)的设计与实现,感兴趣的可以了解一下 在使用 Python 进行编码的时候,会使用自身自带的…

Nginx(3)

目录 1.Nginx虚拟主机1.1基于IP虚拟主机1.2基于端口虚拟主机1.3基于域名实现的虚拟主机 2.日志详解 1.Nginx虚拟主机 虚拟主机,Nginx配置中的多个server{}区域对应不同的业务(站点) 虚拟主机方式基于域名的虚拟主机不同的域名访问不同的站点基于IP的虚拟主机不同的…

纯跟踪(Pure Pursuit)路径跟踪算法研究(1)

纯跟踪(Pure Pursuit)路径跟踪算法研究(1) 下午主要读了几篇论文 《自动泊车路径纯跟踪算法应用研究》 《基于纯追踪算法和樽海鞘优化算法的无人驾驶路径跟踪算法研究》 《基于自适应PP和MPC的智能车辆路径跟踪控制》 首先在公式推导方面还不是很清晰 最…

缓解针对LLM应用程序的存储提示注入攻击

推荐:使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 LLM提供提示文本,并根据其已训练和访问的所有数据进行响应。为了用有用的上下文补充提示,一些 AI 应用程序捕获来自用户的输入,并在将最终提示发送到 LLM 之前将用户看不…

7.5 详解批量规范化 对某个维度取平均值代码解读

一.举例计算均值、方差 假设我们有以下一组数据:[10, 15, 20, 25, 30] 首先,我们计算均值,即将所有数据相加后除以数据的数量: 均值 (10 15 20 25 30) / 5 100 / 5 20 1.1标准差 接下来,我们计算标准差&…

_declspec(naked) 初试(裸函数)

最近在写驱动时候初次使用裸函数,做一些记录 _declspec(naked)修饰可以生成一个“裸”函数, 使用后C编译器将生成不含函数框架的纯汇编代码,裸函数中什么都没有,所以也不能使用局部变量,只能全部用内嵌汇编实现。 可…

使用Presto、Trino数据库时提示“The datetime zone id ‘GMT+08:00‘ is not recognised”

出现这个问题的原因是:Presto、Trino的驱动使用了joda这个库来处理时区的问题。但这个库的编写人似乎对java zone的格式没有太多经验。先看一下出错的代码: com.facebook.presto.jdbc.internal.joda.time.DateTimeZone#forID 根据String类型的zoneId转成…

java日期常用操作

Testpublic void validateDateUtils(){// 1 字符串转换日期Date result DateUtil.parse("2023-08-01", com.alibaba.excel.util.DateUtils.DATE_FORMAT_10);log.info("result : [{}]" , result);// 2 日期转换字符串final Date date new Date();String f…

网络防御之SSL VPN

1. SSL工作过程是什么? 第一阶段: 客户端发送client hello消息到服务端,服务端收到client hello消息后,再发送server hello消息到客户端。 第二阶段: 服务器的证书,用于客户端给客户端发送信息时加密 serv…

韩顺平Linux基础篇

一、课程内容 二、Linux应用领域 一、Linux使用在哪些地方 Linux最强应用:服务器 三、Linux概述 三、Linux和Unix的关系 五、VM和Linux的安装 基本说明 学习Linux需要一个环境,我们需要创建一个虚拟机,然后再虚拟机上安装一个Centos系统来学…

将 Kwargs 传递给 Python 中的另一个函数

文章目录 Python 中的关键字参数在 Python 中使用**kwargs 调用函数使用 Python 将 kwargs 传递给另一个函数总结 Python 列出了可以传递给程序中的函数的两种类型的参数。 非关键字参数 (**args) 和关键字参数 (**kwargs)。 通常,python 函数必须使用正确数量的参…

春秋云镜 CVE-2022-24124

春秋云镜 CVE-2022-24124 Casdoor api 获取组织 SQL注入 靶标介绍 Casdoor是开源的一个身份和访问管理(IAM)/单点登录(SSO)平台,标记支持OAuth 2.0 / OIDC和SAML身份验证的Web UI。 Casdoor 1.13.1之前存在安全漏洞&…