java异常详解

一、异常概述

  异常是用来描述程序运行前或运行中出现的不正常的情况。异常处理是指当程序执行不正常的时候,程序员需要对出现的异常进行处理,也就是提供程序退出的安全通道。

1.1、异常体系图

程序中的异常好比人身上的病,人生病结构体系图和程序异常结构体系图如下:
人生病体系图
在这里插入图片描述

异常体系图:
在这里插入图片描述
所有的异常都继承于Throwable类,其中异常类中有两个重要的子类:错误(Error),异常(Exception)
异常下又存在两个重要的子类:运行时异常(RuntimeException)和非运行时异常(编译时异常)。

错误:错误是比较严重的异常问题,通常与编码者执行的操作无关,与计算机硬件或JVM有关。
常见的错误有:

异常名称异常描述
VartualMachineError虚拟机错误
OutofMemoryErrorr内存溢出
ThreadDeath线程死锁

运行时候异常:运行时异常都是RuntimeException类及其子类异常,这些异常程序中可以选择捕获处理,也可以不处理。
常见的运行时异常有:

异常名称异常描述
java.lang.ArrayIndexOutOfBoundsException数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
java.lang.ArithmeticException算术条件异常。譬如:整数除零等。
java.lang.SecurityException安全性异常
java.lang.IllegalArgumentException非法参数异常
java.lang.ArrayStoreException数组中包含不兼容的值抛出的异常
java.lang.NegativeArraySizeException数组长度为负异常
java.lang.NullPointerException空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。

编译时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
常见的编译时异常:

异常名称异常描述
IOException操作输入流和输出流时可能出现的异常
EOFException文件已结束异常
FileNotFoundException文件未找到异常
ClassCastException类型转换异常类
SQLException操作数据库异常类
NumberFormatException字符串转换为数字抛出的异常

问题: *如何区分错误与异常:
如果程序出现了不正常的信息,如果不正常的信息以Exception结尾,那么就是异常,可以通过代码进行修复
如果异常是以Error结尾,那么就是错误,一般通过硬件配置或者其他非代码引起的错误。

因为都继承于Throwable,所以都可以使用父类的方法,Throwable中常用的方法有:

public string toString();
1. 返回异常发生时的简要描述
例如返回结果:java.lang.Throwable

public string getMessage();
2. 返回异常发生时的详细信息 

public void printStackTrace();
3. 在控制台上打印Throwable对象封装的异常信息
例如返回结果:
java.lang.Throwable
	at test.test(test.java:27)
	at test.main(test.java:23)

二、异常处理

  在 Java 应用程序中,异常处理分为两种:抛出异常,捕捉异常
1. 异常捕获
  程序员对容易出异常的代码块进行异常监控和捕获,当异常出现的时候,将捕获到的异常进行处理。通过做法是将异常和异常信息打印到控制台,让开发人员知晓。

2. 异常抛出
  当程序运行中出现异常,当前方法会创建一个异常对象,并将异常的详细信息抛给调用此程序的方法,调用方法者可对异常就行捕获处理或继续抛给下一个调用者。如果异常无捕获处理,一直向上抛出,那么最终会抛给JVM,JVN会创建一个异常对象,将异常信息打印到控制台和记录日志,让程序员知晓。

2.1、异常捕获

在Java中,异常通过try-catch语句捕获。其一般语法形式为:

格式:
try{
 可能发生的异常…
}catch(捕获的异常类型 变量名){
 处理异常的代码…
}

关键词 try 后的一对大括号将一块可能发生异常的代码包起来,称为监控区域
try块(监控区域)中的代码出现异常的时候,会自动执行catch 中的代码块。
例如:
在这里插入图片描述

异常捕获注意的细节

1、如果try块中的代码出现了异常经过处理之后,那么try…chtch外面的代码可以正常的执行

2、如果try块中发生了异常,try块中异常之后的代码都不会继续执行,在没有return或throw关键字的情况下,try…chtch外面的代码会正常执行。

例如:
在这里插入图片描述
结果:
在这里插入图片描述

3、一个try块后面是可以捕获多种异常情况的,捕获多个异常的时候异常类型大的放在最后捕获,否则将报错。

例如:
在这里插入图片描述
结果:
在这里插入图片描述

面试问题:
既然Exception可以捕获所有的异常,为什么不直接写成Exception呢?
答案:
   因为设置不同的异常是为了返回给用户友好的提示信息,让用户知道是哪里出了问题,而不是返回一大推异常代码,这样用户也看不懂。因为代码出现异常的情况有多种,可能是用户不按规定来录入数据或其他操作导致的异常,这时我们就需要明确的告诉用户是哪里出了异常,或是哪里错了,所以使用Exception来直接捕获所有异常是不好的。

2.2、异常抛出

  所谓的抛出处理就是捕获不了或懒捕获,然后抛给调用者来诊断异常,让调用者来捕获。如果一直抛,没有捕获的,那么最后由JVM来处理,因为方法最终是由JVM来调用了。

异常的抛出通常使用关键字throwthrows

throw 和 throws 关键字的区别:
1、throw关键字是用于方法内部的。throws是用于方法上声明异常的。
2、throw关键字是后面紧跟异常对象,用于方法内部。 throws是用于在方法头部进行声明,后面紧跟一个异常类型。
3、throw后面一次只能抛出一个异常对象。throws后面可以一次性抛出多种类型的对象。

例如:
在这里插入图片描述

异常抛出注意的细节

1、如果一个方法内部抛出了一个"编译时异常"对象,那么必须在方法头上声明抛出
2、如果一个方法内部抛出了一个"运行时异常(RuntimeException)"对象,那么可以在方法头上声明,也可以不声明。
3、如果声明了一个异常抛出的方法,那么调用者必须要处理异常。所谓的处理要么是抛出处理,要么是捕获处理。
4、如果一个方法抛出了一个异常对象,那么throw后面的代码将不会往下执行。(有点像return的作用)
5、try…catch异常处理不需要声明,throw异常处理需要声明。

当使用继承时,在父类的某个方法上声明了throws抛出某些异常,而在子类中重写该方法时,我们可以做以下的操作:
1、父类异常什么样,子类异常就什么样
2、可以抛出父类throws异常中的子类
3、不抛出异常
4、父类方法如果不抛出异常,子类重写也不能抛出异常
5、如果父类方法不抛出异常,但是子类出现异常,也不能抛出,只能子类自己捕获。
但是不能做以下操作:
(1)重写方法时在throws中声明抛出额外的异常
(2)重写方法时在throws中声明父类方法中声明的抛出异常的父类异常
一句话:
一句话总结:当父类坏了,儿子不能比父亲更坏。
父亲没变坏,儿子坏了,儿子的错误自己去解决。

例如:
在这里插入图片描述

三、自定义异常

自定义异常存在背景:
  当程序满足语法要求和编译要求,但是不满足实际业务逻辑时,将不满足业务逻辑的部分部分当成一个异常抛出。比如:业务逻辑要求输入的身份证号是18位,当输入的身份证号少于18位或大于18位时就作为异常异常抛出,这个异常就叫自定义异常。

自定义异常使用:自定义一个类继承Exception即可。

需求:

模拟feiQ上线的时候,如果没有插网线,那么就抛出一个没有插上网线的异常,如果已经插上了网线,那么就正常显示好友列表

自定义异常:
在这里插入图片描述

方法一:使用try…catch的方式处理异常
在这里插入图片描述

方法二:使用throws抛出异常
在这里插入图片描述
结果:
在这里插入图片描述
自定义异常需注意:

1、使用throw方法抛出异常的时候需要使用throws关键字在方法头部进行声明
2、被调用的方法如果声明了抛出异常类型,那么调用者要么使用try…catch来处理异常,要么使用throws往上抛异常。
3、如果使用try…catch来处理,那么被调用者抛出几个异常类型,调用者必须要捕获几个异常类型

四、finally块

finally块必须要有try…catch的时候才能使用。且finally块中的代码无论走catch中的哪个分支都会被执行。
例如:
在这里插入图片描述
结果:
在这里插入图片描述

finally使用注意:

1、哪怕是使用return或throw关键字结束一个程序,但是finally语句还是会执行,除了JVM退出的情况不会执行
2、finally块的代码非常适合作资源释放的动作,这样子可以保证资源文件在任何情况下都会被释放。

例如:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值