Java 中的异常

异常:就是出现的问题。

在Java中异常被当成对象进行处理,所有的异常类都继承于Throwable类,如果Java提供的异常类并不能满足需求,用户还可以自己定义一个异常类。

下面是异常体系结构:

7d1e2d697c3e4834a5cf8e0401abd22a.png

Throwable又分成了Error和Exception。本文仅讨论Exception及其子类,因为Error出现的话也不是我们能够处理的。

Exception又分为RuntimeException和其他异常。

由程序逻辑错误导致的异常属于RuntimeException及其子类异常,也叫不受查(unchecked)异常并不需要进行异常处理,当然也可以处理并不会报错。比如以下几种常见的异常:

①错误的类型转换;

②数组索引越界;

③访问空指针。

而程序本身没有其他问题,由于像IO这类问题导致的异常属于其他异常,也叫受查(checked)异常,必须显示地进行异常处理(捕获或者抛出异常),否则会报错。比如以下这种情况:

①读取本地不存在的文件。

②网络断开连接。

当出现异常时有两种解决方式:

1、捕获异常进行处理,即try - catch捕获异常。

2、将异常传递给方法调用者,即抛出异常。

如果调用了一个抛出异常的方法,那么必须进行处理或传递,如何选择呢?

如果知道如何处理的异常可以进行捕获,而那些不知道怎样处理的异常继续向上抛出。

向上抛出

什么时候需要向上抛出异常?

(1)传递一个危险信号,需要让调用者知道;

(2)本方法没有处理异常的能力,调用方法有能力处理;

(3)抛出是框架层面的选择。

这里介绍一下JVM默认的异常处理方式:

①结束程序的运行,即异常下面的代码就不会执行了;

②将异常信息、异常原因和异常位置以红色字体输出在控制台。

什么是抛出异常?

1、throws

在方法的后面使用throws关键字将可能会抛出的异常进行声明,当方法内出现异常时,会将异常进行抛出,告知方法的调用者。表明当前方法不处理异常,而是把异常交给调用者去处理,如果调用者也不处理,接着向上抛出。具体格式如下:

public Image loadImage(String s) throws IOException {}

2、throw

抛出一个异常。

throw new EOFException();

关于throws和throw两个的细节:

  1. 都是抛出异常,可同时使用,也可单独使用;
  2. 都将异常传递给方法的调用者;
  3. 都会结束当前方法中剩余代码的执行。

捕获异常

使用try-catch语句。捕获单个异常格式如下:

try {     编写可能会出现异常的代码
} catch (异常类型  e)
{     处理异常的代码     //记录日志/打印异常信息/继续抛出异常
}
  1. 如果try语句的任意一行代码中抛出了catch语句能够捕获的异常对象,那么将跳过try语句块中的剩余代码去执行catch中的语句体。
  2. 如果try语句中的任何代码抛出了一个在catch语句中并没有声明的异常类型,那么就会由虚拟机调用默认的异常处理机制,结束程序的运行,并在控制台打印异常有关信息。
  3. 如果try语句中没有代码抛出异常,那么将跳过catch语句。

在一个try语句块中可以捕获多个异常类型,并对不同类型的异常做出不同的处理。可以按照下列方式为每个异常类型使用一个单独的catch子句:

try{编写可能会出现异常的代码
}catch(FileNotFoundException e) {  //当try中出现FileNotFoundException 类型异常,就用该catch来捕获处理异常的代码//记录日志/打印异常信息/继续抛出异常
}catch(UnknownHostException e) {  //当try中出现UnknownHostException 类型异常,就用该catch来捕获处理异常的代码//记录日志/打印异常信息/继续抛出异常
}

注意多个catch语句中的异常类型不能一样,并且父类的异常应该放在子类的后面,否则会报错,因为如果写在最前面的话,异常在第一个岔路口就被抓住了,后面的捕获就多余了,依据Java的严谨性,不允许出现这种情况。

而且异常对象可能包含与异常本身有关的信息。要想获得对象的更多信息,可以试着使用e.getMessage()或者e.printStackTrace()得到详细的错误信息(如果有的话),或者使用 e.getClass().getName() 得到异常对象的实际类型。

在Java SE7中,同一个 catch 子句中可以捕获多个异常类型,中间用 | 进行隔开。例如,假设对应缺少文件和未知主机异常的动作是一样的,就可以合并catch子句:

try {编写可能会出现异常的代码
} catch (FileNotFoundException| UnknownHostException e) {处理异常的代码//记录日志/打印异常信息/继续抛出异常
} catch(I0Exception e) {处理异常的代码//记录日志/打印异常信息/继续抛出异常
}

那么什么时候抛出异常?什么时候捕获异常呢?

解释1

一句话回答就是“没有金刚钻,不揽瓷器活”。

如果你发现了某个问题,你又没能力解决,你就该汇报给上级,这就是【抛出异常】。

如果你接到了下属汇报的问题,你也没能力解决,你就只好再汇报给你的上级,这就是【继续抛出】。

只有你有能力解决的情况下,你才可以把这个问题解决掉,这就是【捕获异常】。

总结就是:谁遇到困难,谁抛出异常。谁解决问题,谁捕获异常。

下层抛出上层进行捕获。

细节1:

如果一个异常没有在任何地方被捕获,那么就会由虚拟机调用默认的异常处理机制,结束程序的运行,并在控制台打印异常有关信息。

前面还没懂吗,你不用throw抛出异常,调用者就接收不到异常,就无法捕获异常并处理,最后会交给虚拟机处理,这样程序就会停止运行,之后的代码无法运行。

给出一个代码例子: 

public class test05 {public static void main(String[] args) {int[] arr = null;try {int max = getMax(arr);} catch (NullPointerException e) {System.out.println("空指针异常");} catch (ArrayIndexOutOfBoundsException e) {System.out.println("索引越界异常");}}public static int getMax (int[] arr) throws NullPointerException, ArrayIndexOutOfBoundsException{int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}return max;}
}

finally

不论是否有异常被捕获,finally子句都将被执行。比如打开了一些资源,但是异常发生时,希望这些文件可以关闭,就可以使用finally。下面举一个例子,其中的1,2...表示代码:

InputStream in = new FileInputStream(...);
try {// 1code that throw exceptions// 2
} catch {// 3show error message// 4
} finally {// 5 in.close();
}
// 6

1、try语句中是否有异常发生? 

①try语句中没有异常发生。那么try语句中的所有代码都会被执行,然后执行finally语句中的所有代码,接着执行finally后面的代码,即执行标注的1,2,5,6。

2、try语句中有异常发生,但是catch语句是否可以捕获?

(1)try语句中发生一个可以由catch语句捕获的异常,而catch语句中是否又抛出了异常?

①catch语句中没有抛出了异常。首先会执行try语句中异常发生之前的代码,然后执行catch语句中的所有代码,接着是finally语句中的所有代码,最后执行finally后面的代码,即执行标注的1,3,4,5,6。

②catch语句抛出了异常。还会执行finally子句吗?必须执行,要不然finally还有什么用呢,就是不会实现finally子句后面的语句了,结束方法的运行。即1,3,5。

警告:当 finally 子句包含return语句时,将会出现一种意想不到的结果。假设使用return语句从try语句块中退出。在方法返回前,finally子句的内容将被执行。如果 finally 子句中也有一个return语句,这个返回值将会覆盖原始的返回值。下面是一个例子:

public static int f(int n) {try {int r= n* n;return r;} finally {if(n == 2)return 0;}
}

如果调用f(2),那么 try语句块的计算结果为r=4,并执行return 语句。然而,在方法真正返回前,还要执行 finally 子句。finally 子句将使得方法返回 0,这个返回值覆盖了原始的返回值 4。

总结就是:假如try和finally子句中都带有return返回值,最终会返回finally子句中的返回值。

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

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

相关文章

vmware配置centos+配置静态ip联网+更换镜像

centos7配置参考【实战】VMware17虚拟机以及Centos7详细安装教程-CSDN博客 ip配置步骤&#xff1a; 先更改编辑虚拟网络编辑器中的内容 就按照还原默认设置来&#xff0c;设定后就是以上内容&#xff0c;然后一定要记住子网ip和子网掩码 接下来就是NAT设置&#xff1a; 网关…

PE安装系统

前些天客户的电脑坏了,需要重装系统,我们的恢复光盘安装的时候,由于主板的原因,导致进入windows安装界面,鼠标键盘没有响应,自然也就无法正常安装了. 那我们只能换个方法,PE安装试试看,那么我们需要做哪些准备工作呢? 1.制作PE启动盘,网上很多制作工具,如""U启动,…

关于 Docker Registry (镜像仓库)

什么是镜像仓库 概念 镜像仓库&#xff08;Docker Registry&#xff09;负责存储、管理和分发镜像&#xff0c;并提供了登录认证能力&#xff0c;建立了仓库的索引。 镜像仓库管理多个 Repository&#xff0c;Repository 通过命名来区分。每个 Repository 包含一个或多个镜像…

P1-AI产品经理--九五小庞

产品经理的定位 AI基于现有业务挖掘AI应用场景&#xff0c;服务提供商选择及算法定制等&#xff0c;配合已有产品完成整体产品工工资基于从事医疗行业的考虑&#xff0c;我们走的应该是AI产品经理&#xff08;软件型&#xff09; AI产品经理&#xff08;行业型&#xff09; AI…

Python爬虫(1) --基础知识

爬虫 爬虫是什么&#xff1f; spider 是一种模仿浏览器上网过程的一种程序&#xff0c;可以获取一些网页的数据 基础知识 URL 统一资源定位符 uniform resource locator http: 超文本传输协议 HyperText Transfer Protocol 默认端口 80 https: 安全的超文本传输协议 security…

通过HTML/CSS 实现各类进度条的功能。

需求&#xff1a;我们在开发中会遇到使用各式各样的进度条&#xff0c;因为当前插件里面进度条各式各样的&#xff0c;为了方便我们定制化的开发和方便修改样式&#xff0c;我们这里使用HTML和CSS样式来进行开发进度条功能。 通过本文学习我们会明白如何使用 HTML/CSS 创建各种…

复旦微核心板:基于复旦微FMQL45T900 全国产化核心板

近期开发的一款搭载复旦微FMQL45T900的全国产核心板。FMQL45T900这款是一款高度集成的国产化芯片&#xff0c;它在一个单芯片中融合了多种功能&#xff0c;特别强调的是它的国产化特性&#xff0c;即其设计、制造和知识产权完全属于中国。 处理器性能&#xff1a; 处理器架构&a…

Python和C++行人轨迹预推算和空间机器人多传感融合双图算法模型

&#x1f3af;要点 &#x1f3af;双图神经网络模型&#xff1a;最大后验推理和线性纠错码解码器 | &#x1f3af;重复结构和过约束问题超图推理模型 | &#x1f3af;无向图模型变量概率计算、和积消息传播图结构计算、隐马尔可夫模型图结构计算、矩阵图结构计算、图结构学习 |…

QT--多页面、定时器和日期时间数据

多页面 widget.ui 负责实现一个页面; mian.cpp创建窗体对象,并监控上面的事件 窗口的显示和隐藏: 一个窗体,比如logpage widget,继承QWidget QWidget::show(); 显示该窗体 QWidget::hide(); 隐藏该窗体 页面间通信采用在main.cpp中创建connect槽函数。 代码如下 //main.c…

【ML练习】决策树

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、决策树算法概述 二、代码实现 代码目标&#xff1a;我们希望通过鸢尾花数据&#xff0c;训练一个决策树模型&#xff0c;之后应用该模型&#xff0c;可以…

STM32 CAN外设(基于STMF103C8T6)

STM32内置bxCAN外设&#xff08;CAN控制器)&#xff0c;支持CAN2.0A和2.0B&#xff0c;可以自动发送CAN报文和按照过滤器自动接收指定CAN报文&#xff0c;程序只需处理报文数据而无需关注总线的电平细节 波特率最高可达1兆位/秒3个可配置优先级的发送邮箱2个3级深度的接…

Java后端开发(十五)-- Ubuntu 开启activemq开机自启动功能

目录 1. 修改Wrapper.conf文件配置内容 2. 在/etc/systemd/system目录下创建activemq.service文件 3. 重启服务器,验证是否生效 4. 系统启动目标问题 操作环境: 1、Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-28-generic x86_64) 2、jdk17.0.11 3、apache-activemq-6.0.1 1. 修…

学习测试10-1自动化 python基础

下载python 要配置环境变量 进入Python的官方下载页面 http://www.python.org/download/安装PyCharm工具&#xff0c;网上可以下载&#xff0c;很多资源&#xff0c;也有免安装的版本&#xff0c;在网上找激活码 链接: https://pan.baidu.com/s/1Y6S_n3KbnjOdE9EDZ5nixw?pwdd…

CentOS 7 yum官方源失效

问题 2024年7月&#xff0c;官方对centos 7停止了维护&#xff0c;yum的源网址mirror.centos.org也已经无法访问。 在此情况下&#xff0c;无法正常使用yum进行安装和更新工具。 在尝试了更换阿里源之后&#xff0c;仍然有部分工具库无法访问。 通用解决方案 1. 打开/etc/y…

AWS Certified Developer Associate备考笔记

AWS Certified Developer Associate备考笔记 缓慢更新中&#xff0c;如果你也正在关注该考试&#xff0c;请点赞后评论感兴趣的章节&#xff0c;可加快我的更新速度 &#x1f603; 文章目录 AWS Certified Developer Associate备考笔记一、IAM二、EC2三、EC2 Instance Storage…

【WordPress插件】Media folder汉化版-媒体文件夹-v5.1.2

WP媒体文件夹(WP Media folder)是一个真正的节省图片加载时间的插件&#xff0c;你可以管理文件和图片&#xff0c;从本地WordPress媒体管理器。该插件还包括一个增强版的WordPress图库管理器&#xff0c;主题 NextGEN图库导入器。 【WordPress插件】Media folder汉化版-媒…

C++的STL简介

0.STL简介 C的STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;是C标准库的一部分&#xff0c;它提供了一套通用的类和函数模板&#xff0c;用于处理数据结构和算法。STL的主要组件包括&#xff1a; 容器分配器算法迭代器适配器仿函数 容器 容…

数据库系统概论:事务与并发一致性问题

随着网络应用的普及&#xff0c;数据库并发问题变得越来越重要。数据库并发指的是多个用户或进程同时访问和操作数据库的能力。它是数据库系统性能优化的重要方面&#xff0c;旨在提高系统的吞吐量和响应时间&#xff0c;以满足多用户同时访问数据库的需求。然而&#xff0c;这…

Linux NFS服务搭建及使用

一、NFS 服务器介绍 nfs &#xff08; Network File System &#xff09;即网络文件系统&#xff0c;其基于 UDP/IP使用 nfs 能够在不同计算机之间通过网络进行文件共享&#xff0c;能使使用者访问网络上其它计算机中的文件就像在访问自己的计算机一样。 二、NFS 服务器的特点 …

Websocket自动消息回复服务端工具

点击下载《Websocket自动消息回复服务端工具》 1. 前言 在进行Websocket开发时&#xff0c;前端小伙伴通常是和后端开发人员同步进行项目开发&#xff0c;经常会遇到后端开发人员接口还没开发完&#xff0c;也没有可以调试的环境&#xff0c;只能按照接口文档进行“脑回路开发…