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 手动抛出一个异常,即手动进行异常类对象的实例化操作。
throw new EOFException();

关于throws和throw两个的细节:

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

捕获异常

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

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

在一个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.rhkb.cn/news/382240.html

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

相关文章

PHP框架详解- symfony框架

文心一言 Symfony框架是一个用PHP语言编写的开放源代码的Web应用框架&#xff0c;旨在加速Web应用程序的开发过程&#xff0c;提高代码的可维护性和可扩展性。以下是对Symfony框架的详细解析&#xff1a; 一、框架概述 起源与开发者&#xff1a; Symfony由SensioLabs&#…

音乐曲谱软件Guitar Pro 8.2 for Mac 中文破解版

Guitar Pro 8.2 for Mac 中文破解版是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xff0c;重现喜爱的歌曲或陪伴自己。 Guitar Pro for Mac 是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xf…

宠物经济纵深观察:口红效应显著,呈可持续发展态势

七月以来&#xff0c;全国各地陆续开启高温模式。和人一样&#xff0c;“毛孩子们”同样也难耐高温&#xff0c;由此&#xff0c;围绕猫猫狗狗的“宠物经济”迅速升温&#xff0c;宠物冰垫、宠物饮水机、宠物烘干机......一系列宠物单品掀起夏日消费热潮。 就在几天前&#xf…

Pytorch学习笔记day4——训练mnist数据集和初步研读

该来的还是来了hhhhhhhhhh&#xff0c;基本上机器学习的初学者都躲不开这个例子。开源&#xff0c;数据质量高&#xff0c;数据尺寸整齐&#xff0c;问题简单&#xff0c;实在太适合初学者食用了。 今天把代码跑通&#xff0c;趁着周末好好的琢磨一下里面的各种细节。 代码实…

这7款高效爬虫工具软件,非常实用!

在当今数据驱动的时代&#xff0c;自动化爬虫工具和软件成为了许多企业和个人获取数据的重要手段。这里会介绍6款功能强大、操作简便的自动化爬虫工具&#xff0c;用好了可以更高效地进行数据采集。 1. 八爪鱼采集器 八爪鱼是一款功能强大的桌面端爬虫软件&#xff0c;主打可…

pico+unity3d 射线交互教程

前期配置&#xff1a;环境配置参考教程一&#xff0c;手部模型参考教程二&#xff0c;场景基于上一篇搭建。 最终效果&#xff1a;手部射线&#xff08;初始不可见&#xff09;对准 UI 显示&#xff0c;按下手柄 Trigger 键与可交互 UI&#xff08;如 Button、Toggle、Slider …

数学建模(7)——Logistic模型

一、马尔萨斯人口模型 import numpy as np import matplotlib.pyplot as plt# 初始人口 N0 100 # 人口增长率 r 0.02 # 时间段&#xff08;年&#xff09; t np.linspace(0, 200, 200)# 马尔萨斯人口模型 N N0 * np.exp(r * t)# 绘图 plt.plot(t, N, labelPopulation) plt.…

【源码阅读】Sony的go breaker熔断器源码探究

文章目录 背景源码分析总结 背景 在微服务时代&#xff0c;服务和服务之间调用、跨部门调用都是很常见的事&#xff0c;但这些调用都存在很多不确定因素&#xff0c;如核心服务A依赖的部门B服务挂掉了&#xff0c;那么A本身的功能将会受到直接的影响&#xff0c;而这些都会影响…

CSS 两种盒模型 box-sizing content-box 和 border-box

文章目录 Intro谨记box-sizing 两个不同赋值的效果区别&#xff1f;宽高的数值计算标准盒模型 box-sizing: content-box; box-sizing 属性的全局设置 Intro 先问一句&#xff1a;box-sizing 和它的两个属性值是做什么用的&#xff1f;以前我并不知道它的存在&#xff0c;也做…

使用 Redis 实现验证码、token 的存储,用自定义拦截器完成用户认证、并使用双重拦截器解决 token 刷新的问题

基于session实现登录流程 1.发送验证码 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff0c;如果不合法&#xff0c;则要求用户重新输入手机号 如果手机号合法&#xff0c;后台此时生成对应的验证码&#xff0c;同时将验证码进行保存&#xff0c;然后再通过短信…

【数据挖掘】词云分析

目录 1. 词云分析 2. Python 中的 WordCloud 库 1. 词云分析 词云&#xff08;Word Cloud&#xff09;是数据可视化的一种形式&#xff0c;主要用于展示文本数据中单词的频率和重要性。它具有以下几种主要用途和意义&#xff1a; 1. 文本分析 • 识别关键主题&#xff1a;通…

AGI 之 【Hugging Face】 的【从零训练Transformer模型】之一 [ 如何寻找大型数据集 ] / [ 构建词元分析器 ] 的简单整理

AGI 之 【Hugging Face】 的【从零训练Transformer模型】之一 [ 如何寻找大型数据集 ] / [ 构建词元分析器 ] 的简单整理 目录 AGI 之 【Hugging Face】 的【从零训练Transformer模型】之一 [ 如何寻找大型数据集 ] / [ 构建词元分析器 ] 的简单整理 一、简单介绍 二、Transf…

数据结构day6

一、思维导图 二、模拟面试 typedef定义函数指针的方式typedef int(*p)(int,int);对void*指针的理解&#xff0c;相关应用万能指针&#xff0c;可以定义形参用来接收任意类型的指针变量&#xff0c;也可以定义函数用来返回任意类型的指针变量例如malloc函数在堆区申请内存&…

组队学习——支持向量机

本次学习支持向量机部分数据如下所示 IDmasswidthheightcolor_scorefruit_namekind 其中ID&#xff1a;1-59是对应训练集和验证集的数据&#xff0c;60-67是对应测试集的数据&#xff0c;其中水果类别一共有四类包括apple、lemon、orange、mandarin。要求根据1-59的数据集的自…

NPS配置域名访问本地应用

架构简易说明&#xff1a; 阿里云云服务器一台&#xff1a;NPS服务端 本地Linux服务器一台&#xff1a;NPS客户端&#xff0c;支持互联网 域名一个&#xff1a;解析到云服务器 1.在nps后台配置TCP隧道信息 其中&#xff0c;服务端口为云服务器的端口 &#xff0c;不要与已存…

Linux ls命令详解

学习 Linux &#xff0c;本质上是学习在命令行下熟悉使用 Linux 的各类命令&#xff1b; 1. Linux 命令通用格式 命令格式&#xff1a;命令 【-选项】【参数】(个别命令不遵循该格式) 短线&#xff08;-&#xff09;是区分选项和参数的标志&#xff0c;选项用来调整命令的功能…

陶德:边种田边写代码,3年300万行,一个人写出了“国产大满贯QT”

这是《开发者说》的第12期&#xff0c;本期我们邀请的开发者是陶德&#xff0c;从小在国企矿山里长大&#xff0c;计算机成绩是文科班里最差的一个&#xff0c;毕业两年找不到工作&#xff0c;睡过公园&#xff0c;讨过剩饭&#xff0c;用打魔兽世界的方式磨炼技术&#xff0c;…

PYTHON学习笔记(四、pyhton数据结构--列表)

&#xff08;1&#xff09;list列表 列表的含义是指&#xff1a;&#xff08;1&#xff09;一系列的按特定顺序排列的元素组成。&#xff08;2&#xff09;python中内置的可变序列。&#xff08;3&#xff09;在python中使用[]定义列表&#xff0c;元素与元素之间使用英文的逗…

数据结构 day4

目录 思维导图&#xff1a; 学习内容&#xff1a; 1. 链表的引入 1.1 顺序表的优缺点 1.1.1 优点 1.1.2 不足 1.1.3 缺点 1.2 链表的概念 1.2.1 链式存储的线性表叫做链表 1.2.2 链表的基础概念 1.3 链表的分类 2. 单向链表 2.1 节点结构体类型 2.2 创建链表 2.…

【手撕数据结构】拿捏单链表

目录 单链表介绍链表的初始化打印链表增加节点尾插头插再给定位置之后插入在给定位置之前插入 删除节点尾删头删删除给定位置的节点删除给定位置之后的节点 查找节点 单链表介绍 单链表也叫做无头单向非循环链表&#xff0c;链表也是一种线性结构。他在逻辑结构上一定连续&…