2021.01.20 第一阶段 13

一、LinkedHashSet

1、是set接口的一个实现类,并且是HashSet的子类,在集合中定义了迭代顺序
2、效果:既能够对元素去重,还能够保证存取顺序一致
3、去重原理和HashSet一致
4、场景:既需要去重有需要保证顺序,就可以考虑使用该类

二、异常

(一)概述
1、在java代码的运行过程中,出现了和正常情况不一样的情况,就是异常
2、异常就是一个对象,描述了和正常情况不符合的异常情况,这个对象中,包含了:异常情况的原因、类型、出现异常的位置
3、异常也是一种机制,可以通过异常实现代码的跳转、实现异常的捕获甚至结束程序等操作
(二)异常的体系
1、Throwable类型:是java中异常和错误体系的总父类,所有的异常信息和错误信息都可以使用Throwable提供的方式来进行处理,只有在Throwable体系内,才能采用异常的处理机制处理异常
2、Error:错误。是Throwable的子类,一般用于描述比较严重的问题和错误,程序员通常无法解决:StackOverError。
3、Exception:异常。是Thorwable的子类,一般用于描述不是很严重的问题和错误,都可以通过修改代码进行处理和解决,也可以通过java的异常处理机制去处理
4、RuntimeException:运行时异常,是Exception的特殊子类,在编译期不会检查
5、体系图:

在这里插入图片描述
(三)JVM的异常默认处理机制
1、在代码的某个位置,出现了和正常情况不一样的情况,这个情况就是一个异常情况,会将异常情况的原因、位置信息等封装到一个异常对象中
2、将异常对象抛给调用该方法的方法
3、某个方法接受到底层抛上来的异常对象,再抛给调用自己的那个方法
4、一层一层向上抛,当对象抛给main方法的时候,main方法将异常对象抛给JVM
5、JVM会将异常的类型、位置、信息、原因等打印在屏幕上,并且关停自己

在这里插入图片描述

三、手动处理异常的方式

(一)概述
1、异常处理的方式有两种:
(1)异常的捕获:在代码运行过程中出现了异常,实际上是会抛出一个异常对象的,我们可以使用既定的格式对异常对象进行捕获并根据情况解决异常,来阻止异常对象抛给虚拟机结束运行
(2)异常的声明:某个方法存在编译时异常的时候,代码会出现像语法错误一样的错误,我们必须对异常进行处理,除了对异常进行捕获以外可以对异常进行生命,在方法的声明上添加异常的声明,用来告知这里可能会出现什么问题,但是如果仅仅是声明,当编译时异常真的发生的时候,还是会按照默认机制处理。
2、捕获异常的格式:
(1)try…catch
(2)try…catch…finally
(3)try…finally
(二)try…catch
1、定义格式

try {
	可能会出现异常的代码
} catch(可能会出现的异常类型 标识符) {
	将捕获到的异常对象进行具体处理的方式
}

2、try:关键字,含义:尝试。我们在书写代码的时候,有些代码可能会出现异常,就将可能会出现异常的代码放在try模块中,如果不出现异常就正常执行,哪一句代码出现异常,后面的代码就不会再去执行了。例如:try中有1、2、3行代码,第1行代码如果出现异常,2、3行代码不会再去执行
3、catch:关键字,含义:捕获。当try中的代码真的抛出了一个异常对象的时候,catch模块就会尝试对这个异常对象进行捕获。如果catch中声明的异常类型恰好是异常对象的相关类型,就进行捕获进而处理,如果声明的异常类型是A,异常对象属于B类型,则无法捕获,按照默认机制处理。如果try中没有抛出异常对象,则catch模块不工作
4、运行机制:
(1)运行try中的代码
(2)如果try中的某一行代码出现异常,try中这行代码后面的代码不会再去执行
(3)catch模块尝试捕获try中的异常对象
(4)如果catch声明的异常类型和异常对象的类型相关,就进行捕获并且处理,处理完毕后try…catch之后的代码正常运行
(5)如果catch声明的异常类型和异常对象的类无关,就无法捕获,按照默认处理机制处理
(6)如果try中的代码没有出现任何异常,catch模块不运行,try…catch之后的代码正常运行

在这里插入图片描述
(三)try…catch…catch…
1、在一段代码中,可能会出现多种异常,但是我们如果只有一个catch,只能捕获一个类型的异常对
象,其余的都要按照默认处理方式去处理,所以添加多个catch,用于捕获不同类型的异常对象
2、格式:

try {
	可能会出现异常的代码
} catch(可能会出现的异常类型1 标识符) {
	将捕获到的异常对象进行具体处理的方式
} catch(可能会出现的异常类型2 标识符) {
	将捕获到的异常对象进行具体处理的方式
} ...... {
} catch(可能会出现的异常类型n 标识符) {
	将捕获到的异常对象进行具体处理的方式
}

3、执行流程:和(二)的流程一样,只是多匹配了几个catch
4、注意事项:
(1)catch模块的匹配顺序:按照从上到下的顺序匹配,抛出一个异常对象后,先和第一个catch声明的异常类型匹配,如果成功,就直接处理异常,处理完毕后执行try…catch之后的代码;如果捕获不成功,再按照顺序匹配下一个,到哪一个匹配成功,就执行哪一个的处理;如果全都匹配不到,按照默认机制处理
(2)由于按顺序匹配catch模块,所以上面的catch模块声明范围较小的异常类型,下面的catch模块声明范围较大的异常类型;如果较大的异常类型声明在上面,较小的在下面,会造成下面较小的类型永远匹配不到
(3)在jdk7开始,一个catch中可以声明多个异常类型了

catch(异常类型1 | 异常类型2 | 异常类型3 标识符) {
		处理操作
}

(4)try模块和catch模块都不能独立存在,需要配合使用
(四)try…catch…finally
1、定义格式:

try {
	可能会出现异常的代码
} catch(可能会出现的异常类型 标识符) {
	将捕获到的异常对象进行具体处理的方式
} finally {
	一定要去执行的代码
}

2、finally:关键字,作用:放在finally模块中的代码,一定会被执行到
3、使用finally的原因:
(1)如果将一定要执行的代码放在try中,如果try中某些代码执行出现了异常,后面的代码不会被执行,所以不能放在try中
(2)一定要执行的代码也不能放在try…catch之后,如果catch没有捕获到已经出现的异常对象,就会按照默认机制处理,try…catch之后的代码就无法执行了
(3)将一定要执行的代码放进finally中,这些代码就一定能被执行到
4、注意事项:
(1)finally模块一般用于关闭资源
(2)finally模块不能独立存在
(五)try…finally
1、定义格式:

try {
	可能会出现异常的代码
} finally {
	一定要去执行的代码
}

2、作用:这种格式的目的就是为了使用默认处理机制处理异常,但是因为存在必须要关闭的资源,所以加上finally模块善后

public class Demo06_TryFinally {
	public static void main(String[] args) {
		try {
			int i = 10 / 0;
		} finally {
			System.out.println("关闭资源");
		}
	}
}

四、编译时异常和运行时异常

1、【无论是编译时异常还是运行时异常,真正发生的时候,都只在运行期】
2、区别:
(1)继承体系的区别:Exception及其子类(出了RuntimeException外),都是编译时异常
RuntimeException及其子类,都是运行时异常
(2)编译期的表现:编译时异常编译期会报错,我们必须通过异常处理手段对异常进行处理才能编译通过
运行时异常编译期没有任何的表现
(3)运行期的表现:编译时异常虽然在编译期通过报错提醒,但是运行期如果逻辑正确就不会发生
运行时异常编译期没有任何的表现,运行时如果有问题会直接抛出异常对象
3、举例:SimpleDateFormat中parse(String time)就会包编译时异常:解析异常

五、异常继承体系中常用方法

1、异常体系中,绝大多数异常类型没有自己特有的方法,构造方法也是按照Throwable类型的构造去定义的,当我们出现异常的时候,异常对象的结构也和Throwable的构造提供的结构相似,也就便于我们将Throwable中的成员方法继承下去并且处理异常
2、Throwable中的构造方法:
(1)Throwable() 创建一个不带有任何详细信息的异常对象
(2)Throwable(String message) 创建一个带有详细信息的异常对象
(3)Throwable(String message, Throwable cause) 创建一个带有详细信息和原因的异常对象
(4)Throwable(Throwable cause) 创建一个带有异常原因的异常对象
3、成员方法:
(1)【printStackTrace()】 打印栈轨迹
(2)getCause() 获取异常对象的原因,如果原因不存在返回一个null
(3)getMessage() 获取异常对象的详细信息
(4)toString() 返回异常信息的简短描述,没有所在线程,没有栈轨迹

六、throw关键字

1、throw:抛出,用于抛出一个实实在在的异常对象
2、当我们运行的过程中,代码出现了异常,会抛出一个异常对象,这个异常对象中包含了异常的各个内容
3、我们在开发中,如果碰到有分歧的情况,可以通过throw关键字抛出一个异常对象,来实现我们代码的跳转甚至停止
4、说明:
(1)如果抛出的是运行时异常,那么这个异常可以不做任何的异常处理,如果不发生就没有问题,发生了直接抛出一个异常对象
(2)如果抛出的是编译时异常,那么这个异常在运行前必须做出异常的处理,可以是异常的捕获,可以是异常的声明,但是运行的时候没有问题不会将异常对象抛出,如果有问题则将异常抛出,并且按照我们提前设定好的方式处理异常对象

七、throws关键字

1、throws,抛出,用于在方法的声明上进行一个或者是多个异常类型的声明
2、在某个方法中,如果存在编译时异常,就必须要对这个编译时异常进行处理,处理出了try…catch捕
获之外,还可以通过throws对存在的异常进行手动声明处理
3、格式:

修饰符 【static】 返回值类型 方法名(参数列表) throws 异常类型1, 异常类型2, ..., 异常类型n) {

}

4、注意事项:
(1)如果通过throw关键字抛出了一个实实在在的异常对象,这个异常如果是运行时异常,那么不需要通过throws关键字在方法上进行异常类型的声明
(2)如果通过throw关键字抛出了一个实实在在的异常对象,这个异常如果是编译时异常,我们此时就必须进行异常处理,可以用throws关键字在方法上进行异常类型的声明(也可以用try…catch捕获)
(3)A方法存在编译时异常,B调用了A方法,那么B也就相当于有了编译时异常,B方法也就需要进行异常处理,如果此时B方法进行了异常的声明,C又调用了B,C可以选择异常的声明或者捕获;如果B进行了异常的捕获,C调用了B,C相当于没有异常
(4)在声明异常类型的时候,声明尽量小、尽量少的异常类型

八、throw和throws的区别

1、throw关键字是对异常【对象】的抛出,throws关键字是对异常【类型】的声明
2、throw关键字是对异常【对象】的【实实在在】抛出,throws关键字虽然对异常的类型进行了声明,但是异常到底会不会发生也不一定
3、throw关键字后面只能跟一个异常对象,throws关键字后面只能跟多个异常类型

九、方法重写的补充

1、重写:在子父类中,方法名称相同,参数列表相同,与返回值类型有关
2、与返回值类型有关:父类方法的返回值类型如果是A,子类重写这个方法,返回值类型可以是A也可以是A的子类
3、私有的方法不能被重写
4、方法重写时,权限修饰符范围可以不变,可以越来越大,不能变小
5、父类方法没有生命异常,子类重写的方法如果出现了异常,只能try…catch,不能throws
6、如果父类方法声明了A类型的异常,子类重写的方法可以声明异常,但只能是A或者A的子类类型

十、自定义异常

1、JDK中提供了非常多的异常类型,实际上就是为了我们一看到异常类型就知道出现了一个什么异常,目的在于见名知意。但是实际开发中,很多情况下JDK提供的类名都不够用,例如:年龄非法,JDK没有提供年龄非法异常,此时可以自定义一个类型,按照见名知意作为异常类型。
2、注意:当我们创建好一个类型的时候,它并不是异常,因为JDK中所有的异常都在Exception体系下,沿用Throwable类型的方式,才能对异常进行声明和捕获
3、步骤:
(1)自定义类型,继承Exception或者RuntimeException,让其作为编译时异常或者运行时异常
(2)为了方便后续处理异常对象,所以在自定义类中按照父类的结构提供相应的构造方法
(3)根据具体情况,使用throw抛出异常对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值