异常(throwable)

news2024/9/24 15:25:11

异常

异常分类

(1)Throwable类

所有的异常类型都是它的子类,它派生两个子类Error、Exception。

(2)Error类

表示仅靠程序本身无法恢复的严重错误(内存溢出动态链接失败、虚拟机错误),应用程序不应该抛出这种错误(一般由虚拟机抛出)

(3)Exception类

由Java应用程序抛出和处理的非严重错误

(4)运行时异常(RuntimeException及其子类)

(5)非运行异常(Checked异常)

除了运行时异常外的其它由Exception继承来的异常类

在这里插入图片描述

Exception异常类型

异常说明
Exception异常层次结构的根类(父类)
ArithmeticException算术错误
ArrayIndexOutOfBoundsException数组下标越界
NullPointerException尝试访问Null对象成员
ClassNotFoundException不能加载所需的类
InputMismatchException欲的到的数据类型与实际不匹配
IllegaArgumentException方法接收到非法参数
ClassCastException对象强制转换出错
NumberFormatException数字格式化异常

运行时异常(RuntimeException)

异常说明
ClassCastException类型转换出错
NullPointerException空指针异常
ArrayIndexOutOfBoundsException数组下标越界
ArithmeticException算术异常
ArrayStoreException数组中包含不兼容的值抛出的异常
NumberFormatException字符串转换为数字抛出的异常
IllegaArgumentException方法接收到非法参数
FileSystemNotFoundException文件系统未找到异常
SecurityException安全性异常
StringIndexOutOfBoundsException字符串索引超出范围
NegativeArraySizeException数组长度为负异常

非运行时异常(Checked)

RuntimeException类及其子类异常以外的异常,是必须进行处理的异常,如果不处理,程序就不能编译通过

异常说明
ClassNotFoundException未找到相应类异常
SQLException操作数据库异常类
IOException输入/输出流异常
TimeoutException操作超时异常
FileNotFoundException文件未找到异常

处理异常

try-catch

凡是可能抛出异常的语句,都可以用try-catch捕获。把可能发生异常的语句放在try { }中,然后使用catch捕获对应的Exception及其子类

try-catch-finally

try:可能出现异常的代码块,出现异常,则跳转到catch(必须)
catch:输出异常信息(可选)
finally:必须执行的代码(可选)

catch块中,调用异常对象的方法输出异常信息
(1)void printStackTrace():输出异常的堆栈信息
(2)String getMessage():返回异常信息描述字符串

多重catch

try-catch-catch-finally

JVM在捕获到异常后,会从上到下匹配catch语句,匹配到某个catch后,执行catch代码块,然后不再继续匹配
(1)使用多重catch时,catch块的排列顺序必须从子类到父类,最后一个一般是Exception
(2)运行时,只执行一个catch块
(3)存在多个catch的时候,catch的顺序非常重要:子类必须写在前面

finally

finally语句保证了有无异常都会执行,它是可选的

(1)finally语句不是必须的,可写可不写
(2)finally总是最后执行
如果没有发生异常,就正常执行try {}语句块,然后执行finally
如果发生了异常,就中断执行try {}语句块,然后跳转执行匹配的catch语句块,最后执行finally


finally和return的执行顺序

(1)执行try中的return时

try {
	return 1;
} finally {
	System.out.println("finally模块被执行");
}

finally语句在return语句执行之后return返回结果之前执行
执行结果:先输出finally模块被执行,然后执行在return 1;

(2)执行catch中的return时

try {
	int a = 8 / 0;
return 1;
} catch (Exception e) {
	return 2;
} finally {
	System.out.println("finally模块被执行");
}

程序是从try代码块或者catch代码块中返回时,finally中的代码总会执行
而且finally语句在return语句执行之后return返回之前执行的。可以使用编译器的Debug功能查看详细过程
执行结果:try语句报错,执行输出finally模块被执行,catch中的return 2

(3)finally也有return的时候

try {
	int a = 8 / 0;
	return 1;
} catch (Exception e) {
	return 2;
} finally {
	System.out.println("finally模块被执行");
	return 2;
}

当finally有返回值时,会直接返回。不会再去返回try或者catch中的返回值

(4)finally中对于返回变量做的改变会影响最终的返回结果吗

public int show() {
	int result = 0;
	try {
		return result;
	} finally {
		System.out.println("finally模块被执行");
		result = 1;
	}
}

并不会改变返回的内容

当返回的变量的类型是引用类型时,结果也是一样的

public Object show() {
	Object obj = new Object();
	try {
		return obj;
	} finally {
		System.out.println("finally模块被执行");
		obj = null;
	}
}

如果try和catch的return是一个变量时且函数的是从其中一个返回时,后面finally中语句即使有对返回的变量进行赋值的操作时,也不会影响返回的值。


声明异常、抛出异常

1.声明异常(throws)

(1)通过try-catch捕获并处理异常
(2)通过throws继续声明异常。如果调用者不打算处理异常,则可以继续通过throws声明异常,让上一级调用者处理异常,main()方法声明的异常将由Java虚拟机来处理


2.抛出异常(throw,手动抛出异常)

在代码中需要抛出异常时,尽量使用JDK已定义的异常类型。例如,参数检查不合法,应该抛出IllegalArgumentException:

static void process1(int age) {
	if (age <= 0) {
		throw new IllegalArgumentException();
	}
}
class MyException extends Exception { // 创建自定义异常类
	public MyException(String ErrorMessagr) { // 父类方法
		super(ErrorMessagr); 
	}
}
// 使用自定义异常
throw new MyException("发生了自定义的异常");  

throw和throws不同

throwthrows
作用不同用于程序中抛出异常用于声明在该方法内可能抛出的异常
使用位置不同位于方法体内部,可以作为单独语句使用必须跟在方法参数列表的后面,不能单独使用
内容不同抛出一个异常对象,而且只能是一个后面跟异常类,而且可以跟多个异常类

自定义异常

自定义新的异常类型,但是,保持一个合理的异常继承体系是非常重要的

一个常见的做法是自定义一个BaseException作为“根异常”,然后,派生出各种业务类型的异常自定义新的异常类型,但是,保持一个合理的异常继承体系是非常重要的

BaseException需要从一个适合的Exception派生,通常建议从RuntimeException派生,自定义的BaseException应该提供多个构造方法

public class BaseException extends RuntimeException {
    public BaseException() {
        super();
    }

    public BaseException(String message, Throwable cause) {
        super(message, cause);
    }

    public BaseException(String message) {
        super(message);
    }

    public BaseException(Throwable cause) {
        super(cause);
    }
}

上述构造方法实际上都是原样照抄RuntimeException。这样,抛出异常的时候,就可以选择合适的构造方法。通过IDE可以根据父类快速生成子类的构造方法

其他业务类型的异常就可以从BaseException派生:

public class UserNotFoundException extends BaseException {}
public class LoginFailedException extends BaseException {}

(1)抛出异常时,尽量复用JDK已定义的异常类型
(2)自定义异常体系时,推荐从RuntimeException派生“根异常”,再派生出业务异常
(3)自定义异常时,应该提供多种构造方法


1.继承Exception

自定义异常类继承自Exception类;需要检查编译期异常和运行期异常

// 或者继承RuntimeException(运行时异常) 
public class MyException extends Exception {
	private static final long serialVersionUID = 1L;
	
	public MyException() { // 提供无参数的构造方法
	}

	// 提供参数构造,把参数传递给Throwable的带String参数的构造方法
	public MyException(String message) {
		super(message);
	}
}

serialVersionUID作用:序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性

2.抛出自定义异常方法

写一个测试分数的方法类:这里面是抛出一个自己写的异常类

public class CheckScore { 
	// 检查分数合法性的方法check() 如果定义的是运行时异常就不用抛异常了 
	public void check(int score) throws MyException {
		if (score > 120 || score < 0) {
			// 分数不合法时抛出异常,new一个自定义异常类 
			throw new MyException("分数不合法,分数应该是0--120之间");
		} else { 
			System.out.println("分数合法,你的分数是" + score); 
		} 
	} 
} 

3.测试自定义异常

写一个测试分数,如果有异常,要捕获,不要抛出了

public class Student { 
	public static void main(String[] args) { 
		Scanner sc = new Scanner(System.in); 
		int score = sc.nextInt(); 
		CheckScore check = new CheckScore(); 
		try { 
			check.check(score); 
		} catch (MyException e) {
			// 用自定义异常类来捕获异常 
			e.printStackTrace();
		}
	}
}

自定义异常类继承自RuntimeException类;只需要检查运行期异常
仅仅为了提示,又不想自定义一个Exception,可以用RuntimeException。这个可以抛出异常,并准确定位,缺点是不能处理这个异常,自定义异常的话可以捕获并且处理。


使用断言(了解)

断言(Assertion)一种调试程序的方式。在Java中,使用assert关键字来实现断言
(1)断言是一种调试方式,断言失败会抛出AssertionError,只能在开发和测试阶段启用断言
(2)对可恢复的错误不能使用断言,而应该抛出异常
(3)断言很少被使用,更好的方法是编写单元测试

语法

语句assert x >= 0;即为断言,断言条件x >= 0预期为true。如果计算结果为false,则断言失败,抛出AssertionError

使用assert语句时,还可以添加一个可选的断言消息
assert x >= 0 : “x must >= 0”;
这样,断言失败的时候,AssertionError会带上消息x must >= 0,更加便于调试

Java断言的特点:断言失败时会抛出AssertionError,导致程序结束退出。因此,断言不能用于可恢复的程序错误,只应该用于开发和测试阶段

对于可恢复的程序错误,不应该使用断言

void sort(int[] arr) {
    assert arr != null;
}

应该抛出异常并在上层捕获

void sort(int[] arr) {
	if (arr == null) {
	        throw new IllegalArgumentException("array cannot be null");
	}
}

一个简单的断言

public static void main(String[] args) {
    int x = -1;
    assert x > 0;
    System.out.println(x);
}

开启断言

JVM默认关闭断言指令,即遇到assert语句就自动忽略,不执行;也就是上方断言不会抛出异常AssertionError

选择地对特定地类启用断言,命令行参数是:-ea:com.itranswarp.sample.Main,表示只对com.itranswarp.sample.Main这个类启用断言。
或者对特定地包启用断言,命令行参数是:-ea:com.itranswarp.sample…(注意结尾有3个.),表示对com.itranswarp.sample这个包启动断言。实际开发中,很少使用断言。更好的方法是编写单元测试

要执行assert语句,必须给Java虚拟机传递-enableassertions(可简写为-ea)参数启用断言
java -ea Main.java





上一篇:日期与时间                        下一篇:Java日志处理




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

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

相关文章

分布式定时任务

本文引用了谷粒商城的课程 定时任务 定时任务是我们系统里面经常要用到的一些功能。如每天的支付订单要与支付宝进行对账操作、每个月定期进行财务汇总、在服务空闲时定时统计当天所有信息数据等。 定时任务有个非常流行的框架Quartz和Java原生API的Timer类。Spring框架也可以…

【面试题】20个常见的前端算法题,你全都会吗?

现在面试中&#xff0c;算法出现的频率越来越高了&#xff0c;大厂基本必考 今天给大家带来20个常见的前端算法题&#xff0c;重要的地方已添加注释&#xff0c;如有不正确的地方&#xff0c;欢迎多多指正&#x1f495; 大厂面试题分享 面试题库 前后端面试题库 &#xff08;…

Spring 6 正式“抛弃”feign

近期&#xff0c;Spring 6 的第一个 GA 版本发布了&#xff0c;其中带来了一个新的特性——HTTP Interface。这个新特性&#xff0c;可以让开发者将 HTTP 服务&#xff0c;定义成一个包含特定注解标记的方法的 Java 接口&#xff0c;然后通过对接口方法的调用&#xff0c;完成 …

Simulink仿真封装中的参数个对话框设置

目录 参数和对话框窗格 初始化窗格 文档窗格 为了更加直观和清晰的分析仿真&#xff0c;会将多个元件实现的一个功能封装在一起&#xff0c;通过参数对话框窗格&#xff0c;可以使用参数、显示和动作选项板中的对话框控制设计封装对话框。如图所示&#xff1a; 参数和对话框…

刘二大人《Pytorch深度学习实践》第六讲逻辑斯蒂回归

文章目录线性回归和逻辑斯蒂回归的区别课上代码交叉熵函数的理解线性回归和逻辑斯蒂回归的区别 线性回归一般用于预测连续值变量&#xff0c;如房价预测问题。 线性回归的一般表达式为&#xff1a; 代价函数为MSE&#xff08;均方误差&#xff09;&#xff1a; 其中权重thet…

Linux Shell 实现一键部署二进制Rabbitmq

rabbitmq 前言 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff08;亦称面向消息的中间件&#xff09;。RabbitMQ服务器是用Erlang语言编写的&#xff0c;而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代…

openai的whisper语音识别介绍

openAI发布了chatgpt&#xff0c;光环一时无两。但是openAI不止有这一个项目&#xff0c;它的其他项目也非常值得我们去研究学习。 今天说说这个whisper项目 https://github.com/openai/whisper ta是关于语音识别的。它提出了一种通过大规模的弱监督来实现的语音识别的方法。…

C++之深入解析STL unordered_map的底层实现原理

C STL 标准库中&#xff0c;不仅是 unordered_map 容器&#xff0c;所有无序容器的底层实现都采用的是哈希表存储结构。更准确地说&#xff0c;是用“链地址法”&#xff08;又称“开链法”&#xff09;解决数据存储位置发生冲突的哈希表&#xff0c;整个存储结构如下所示&…

JVM 垃圾收集器详解

一、垃圾收集器 如果说收集算法是内存回收的方法论&#xff0c;那垃圾收集器就是内存回收的实践者。《Java虚拟机规范》中对垃圾收集器应该如何实现并没有做出任何规定&#xff0c;因此不同的厂商、不同版本的虚拟机所包含的垃圾收集器都可能会有很大差别&#xff0c;不同的虚…

基于遗传算法的中药药对挖掘系统的设计与实现

用数据挖掘技术研究了中药方剂配伍的规律。主要工作&#xff1a;分析了关联规则存在的问题&#xff0c;引入双向关联规则的概念&#xff1b;介绍了遗传算法的基本原理&#xff0c;研究了遗传算法在数据挖掘中的应用&#xff1b;将方剂库转换为位图矩阵&#xff0c;大大提高搜索…

Mac重启清理缓存会怎么样 mac清理缓存怎么清理

众所周知&#xff0c;Mac电脑有着流畅的操作系统&#xff0c;因此&#xff0c;很多用户都会选择使用Mac电脑办公。随着日常使用&#xff0c;系统缓存数据越来越大&#xff0c;某些Mac电脑&#xff08;尤其是小内存版本的Mac电脑&#xff09;可能会出现“系统”占存储空间比例较…

初始单片机.md

1.如何将HEX文件烧录到单片机 STC-ISP STC-ISP是一款单片机下载编程烧录软件&#xff0c;是针对STC系列单片机而设计的&#xff0c;可下载STC89系列、12C2052系列和12C5410等系列的STC单片机&#xff0c;使用简便。 思路&#xff1a;将电脑磁盘上已存在的文件通过串口的方式下…

python中第三方库xlrd和xlwt的使用教程

excel文档名称为联系人.xls&#xff0c;内容如下&#xff1a; 一、xlrd模块用法 1.打开excel文件并获取所有sheet import xlrd# 打开Excel文件读取数据 data xlrd.open_workbook(联系人.xls)sheet_name data.sheet_names() # 获取所有sheet名称 print(sheet_name) # [银…

python依次运行多个代码遇到的同步与异步问题

1、要实现在一个Python代码运行完后紧接着运行另一个Python代码&#xff0c;可以使用Python的subprocess模块。该模块可以创建新进程并与之交互&#xff0c;可以用于在Python代码中启动新的程序或脚本。 下面是一个示例代码&#xff0c;用于在运行完code1.py后紧接着运行code2…

论文配色方案(收藏)

方案一&#xff1a;复古 系列色——十六进制颜色码&#xff1a; 0780cf - 765005 - fa6d1d - 0e2c82 - b6b51f - da1f18 - 701866 - f47a75 - 009db2 - 024b51 - 0780cf - 765005 系列色——RGB颜色值&#xff1a; &#xff08;7,128,207&#xff09;-&#xff08;118,80,5&…

【记录】优化油猴插件【BD网盘播放器】

收获最重要前言优化代码收获1.禁止浏览器弹窗2.定时器3.设置属性-隐藏元素4.鼠标悬停和移开事件5.添加元素6.div里均匀分布7.获取元素属性值8.监听播放器状态9.jQuery 选择器前言 有钱的可以支持一下原作者&#xff0c;没钱就要多学习 优化 1.1 视频刚开始未播放时&#xff…

酷雷曼一站式图片直播,助力品牌高效传播

传统模式下&#xff0c;摄影师拍摄会议、活动现场的照片后&#xff0c;一般需要7-10天时间才能完成成片交付&#xff0c;而实际上&#xff0c;由于新闻宣传的即时性&#xff0c;照片延迟交付&#xff0c;远远不能满足客户的需求。因此&#xff0c;即时图片直播技术应运而生&…

Jenkins自动化部署实例讲解

文章目录 前言实例讲解基本环境全局工具配置创建任务任务配置源码管理构建步骤&#xff08;Build Steps&#xff09;第一步&#xff1a;调用Maven第二步&#xff1a;执行shell启动容器 后记 前言 你平常在做自己的项目时&#xff0c;是否有过部署项目太麻烦的想法&#xff1f;…

哈希应用——位图(bitset)

目录 见见猪跑(初步了解位图) 位图的模拟实现 位图的应用 1、给定100亿个整数&#xff0c;设计算法找到只出现一次的整数 2、给两个文件&#xff0c;分别有100亿个整数&#xff0c;我们只有1G内存&#xff0c;如何找到两个文件交集&#xff1f; 3、位图应用变形&#xff…

第六章 Gated RNN

目录6.1 RNN的问题6.1.1 RNN的复习6.1.2 梯度消失和梯度爆炸6.1.3 梯度消失和梯度爆炸的原因6.1.4 梯度爆炸的对策6.2 梯度消失和LSTM6.2.1 LSTM的接口6.2.2 LSTM层的结构6.2.3 输出门6.2.4 遗忘门6.2.5 新的记忆单元6.2.6 输入门6.2.7 LSTM的梯度的流动6.3 LSTM的实现6.4 使用…