Java之异常知识分享

前言

最近新学了Java中异常的相关知识,这边给自己总结一下,方便以后进行知识点回顾~大家也可以跟我一起探讨学习哦~

异常学习的思维导图:


目录

1.异常是什么?(本质+大概的继承结构)

2.编译时异常和运行时异常

3.处理异常

4.自定义异常+小练习


1.异常是什么?(本质+大概的继承结构)

     字面意思,异常可以理解为非正常的事件,而在Java中,异常是程序执行时发生的非正常事件。如果程序员不处理,最终让JVM去处理时,程序正常执行就会发生中断。它的本质其实就是类,其大概继承结构如下:


2.编译时异常和运行时异常

     编译时异常(受查异常):在代码编译的时候,若不声明异常或处理异常那么就无法编译成功

如示例:

所以克隆不支持异常属于编译时异常(受查异常)。 

    运行时异常(非受查异常):只有程序运行起来的时候,才会报错

如示例:

不会报编译的错误,但是一运行:


3.处理异常

     处理异常主要分为两大方式和五个关键字,其主要流程我会根据所画流程图进行理解记忆。

     1)两大方式:

        ● 事前防御型:在执行相关操作之前就检查是否有异常。比如用户进行登录时,输入用户名要检查用户名是否错误,输入密码也要检查密码是否错误,在登录操作执行之前都得判断用户对应成员属性是否错误。

        ● 事后认错型:   按照一定逻辑先执行代码,遇到异常再去处理。 我们先根据用户输入信息进行登录,直到遇到某个异常再去处理,执行对应的处理逻辑代码。(常用)

注:事前防御型将正常代码逻辑和处理异常的代码杂糅在一起,代码显得没有那么直观,而事后认错型将正常代码逻辑和处理某个异常的代码分开执行,代码会更加清晰明了,可读性也会更好,所以我们通常都是使用事后认错型的方式去处理异常

   2)五个关键字:throws, throw, try-catch(try和catch两个关键字组合在一起使用), finally

      ● throws :声明异常,在编译时异常编译失败时,除了直接去处理它能让编译不报错之外,使用throws关键字去声明对应出现的异常也能使编译不再报错。在之前,我们使用未实现Cloneable接口的类对象去调用clone()方法,就会出现CloneNotSupportedException编译时异常:

 我们试着点击Add exception to method signature:

 编译不报错了?仔细一看,原来是调用clone()的函数使用throws关键字声明了该异常:

既然不报错了,那是不是就代表我的程序就能正常运行了呢?我们来运行一下:

 

所以我们可以得出throws声明异常关键字并不能处理异常,它只能让代码编译不报错。 

      ● throw:抛出异常。当用户输入密码不正确的时候,我们可以在对应位置抛出对应异常,才能捕获到它。就像某个地方发生火灾的时候,要及时打电话告诉消防员火情位置,这样消防员才能去灭火。

      ● try-catch:捕获并处理异常,throw抛出的异常往往会被catch捕获,catch捕获成功后就能在对应代码块对捕获到的异常进行处理。如刚才的克隆不支持异常,我们可以使用try-catch对它进行处理这样就能编译和运行都能成功,且能继续执行异常发生处之后的代码:

程序运行结果:

 

hello没有被打印出来。 

 

 hello被打印出来了。

 由此对比我们就可以知道出现异常如果不对其进行处理,那么出现异常后面的代码(不在try代码块中)就不会执行。接下来给大家分享我的自创捕异词哈哈哈哈哈哈,无聊的时候想的:

处理异常需注意

try中代码存多异

从上往下先捕获

每次只捕一个异(try代码块出现多个异常,按出现先后捕获,且每次只捕获一个异常)

异后代码不执行(try代码块出现首个异常,后面代码都不会执行,不在try代码块中的正常代码会执行)

不自大捕全异(尽量不要直接捕获Exception类对象(所有异常包含在内),那具体你捕获的哪种异常就无法得知了)

捕单异全兜底(捕获异常时,你只清楚某几个可能出现的异常,而其它异常未知,你可以在最后直接捕获Exception类对象(所有异常包含在内))

多选一不可取(用 | 连接多个可能出现的异常,那么就无法确定你捕获的是这些异常中的哪一中异常)

注:try中没有出现非运行时异常的异常时,无法使用catch去捕获哦~

奉上我的异常处理流程图:

      ● finally:因为异常发生就会导致某些代码执行不到,而有些特定的代码不论是否发生异常都必须执行,比如关闭输入输出流,数据库连接等只要涉及到资源回收的代码都必须执行。所以我们把这些代码(资源回收)都放在finally代码块中执行

注:尽量不要在finally中设置返回值,因为finally代码块中代码无论有没有异常都会执行,会把原本需要的返回值替换,会造成返回值错误。

4.自定义异常+小练习

     有些情况下,我们需要抛出的异常是Jdk自带异常无法准确描述的,这时候我们就要自己实现继承自Exception类或其子类的自定义异常类。比如用户信息输入异常,新增图书异常等等。

     小练习内容:实现登录功能过程中抛出用户名和密码异常

     ● 分别创建自定义用户名和密码异常类(继承自Exception类或其子类):

     

     

    

    ● 在User类中定义用户名及密码两个成员变量并就地初始化,实现登录功能,当用户名或密码输入错误时,抛出对应的自定义异常:

 ●  因为login函数会抛出异常,所以我们需要在main方法中使用try-catch去捕获并处理对应的自定义异常:

  ●  测试是否会抛出指定异常:

自定义用户名异常:

自定义密码异常:

如果用户名和密码都错误,该抛出哪个异常呢?答案是用户名异常,因为用户名异常比密码异常先抛出:

 

测试完毕!


 关于Java异常的知识总结完毕!老样子:欢迎大家与我一起学习讨论~

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值