Javase——异常

发布时间:2024-06-26 08:01

一、概述

异常就是java程序出现的不正常的情况。(程序中出现的问题)

二、由来

问题在现实生活中也是一个具体的事物,所以也可以用 java 类的形式来描述,封装成对象。其实就是就ava对不正常情况的描述。

三、异常的分类

Javase——异常_第1张图片

(一) Error(错误)

不处理。

(二) Exception(异常)

(1) 编译期异常:不是RuntimeException的异常,必须改代码。
(2) 运行期异常:RuntimeException以及所有的子类。
大部分原因都是因为代码不够严谨导致,很多时候都可以通过改进代码来解决。但是也有一些问题我们在写代码的时候预测不到。我们就需要进行处理。如果没有处理,最终会走jvm的默认处理机制:把异常的名字,原因和位置等信息输出到控制台上。同时程序会结束。
Javase——异常_第2张图片

四、jvm的默认处理机制

把异常的名字,原因和位置等信息输出到控制台上。同时程序会结束。

Javase——异常_第3张图片
对上述代码解析
Java中把常见的异常进行了描述并封装成了对象的类,例如在上面代码中出现了索引越界异常,Java存在ArrayIndexOutOfBoundsException类。当除0运算发生后,出现了一个具体的该类型的错误。jvm会把问题打包成一个具体的异常对象,并交给调用者main 函数——new ArithmeticException()
Javase——异常_第4张图片
main函数在接收到这个问题之后,有2种处理方式
(1) 自己处理,然后程序继续运行
(2) 自己没有处理,最后main函数就只能交给它的调用者jvm来处理。这个不是我们想要的。我们希望的是即使程序种出现问题,应该把问题记录下来,程序继续执行。不应该结束。

五、异常处理方法

(一) try…catch…finally

(1) 格式

try{
	可能出现问题的代码
}catch(异常类名 变量名){
	针对问题的处理
}finally{
	释放资源
}

变形

try...catch
try...catch...catch...
try...catch..cath...finally
try...finally

(2) 使用细节

try…catch 处理多个异常时

多个平级异常
Javase——异常_第5张图片
多个子父级关系异常
Javase——异常_第6张图片
注意

  • try里面的代码越少越好。肯定不会出问题的代码不要写里面。
  • catch中必须有内容。哪怕就是一个输出语句都行
  • 平级关系谁先谁后无所谓,如果有子父级关系,父级必须在后面
  • 能明确类型尽量明确,不要用大的来处理。
  • 一旦try中出现问题,就会在这里把问题对象抛出去,和后面的catch匹配。一旦匹配成功,就执行对应的catch里面的处理方式,然后try…catch就会结束。继续执行后面的代码。

jdk7之后出现的一种处理方案

多个异常使用同一种处理方案

try{
	可能出现问题的代码
}catch(异常类名1|异常类名2|... 变量名){
	处理方案
}finally{
	释放资源
}

注意:多个异常之间必须是平级关系

(3) 编译期异常和运行期异常的区别

编译期异常:必须改代码,否则编译不通过。
运行期异常:可以处理,也可以不处理,也可以和编译期异常一样通过改进代码来解决。

(二)Throwable中的常用方法

获取异常信息的方法
String toString() : 异常的类型和原因
String getMessage() : 异常的原因
void printStackTrace() : 异常的类型,原因和位置,JVM底层也调用的此方法
void printStackTrace(PrintStream s) :这个方法是用于把异常的信息保存到日志文件中,方便后期查看

(三) throws

(1) 说明

编写一个方法的时候,需要把可能出现的问题暴漏出来交给调用者取处理的时候,就需要通过throws在方法上声明。有些异常我们可以处理,有能力处理。但是又有些异常我们处理不了,或者我们没有能力没有权限去处理的时候,我们就需要交给能处理的人来处理。这个时候我们就需要用throws 把问题抛出去。

(2) 格式

throws 异常类名 这个格式必须跟在方法的 () 后面

(3) 注意事项

尽量不要在main方法上抛。(否则会走jvm默认处理机制)
编译期异常的抛出,将来调用者必须处理
运行期异常的抛出,调用者可以处理也可以不处理。

Javase——异常_第7张图片

(四) throw 抛异常

throw throws
用在方法内部,后面跟的是异常对象 用在方法声明上的,后面跟的是异常的类名
只能抛出一个异常对象 可以抛多个异常类名,用逗号隔开
表示抛出异常,由方法内部处理 表示抛出异常,将来由方法的调用者来处理
throw抛的是异常对象,执行了throw就一定产生了某种异常 throws表示的是一种可能性,并不一定会发生

Javase——异常_第8张图片

(五) 如何选择处理异常方法

(1) 原则

如果该代码能解决就改代码,
如果改代码解决不了就用try…catch
如果try…catch也解决不了,就用throws交给调用者处理

(2) 区别

后续代码还想继续执行就用try
后续代码不需要继续执行就用throws

(六) finally

(1) 特点

被finally控制的代码一定会执行
除了特殊情况:在执行到finally之前jvm退出了
Javase——异常_第9张图片

(2) 作用

主要用于释放资源,后面流会见到

(3) 相关问题

final,finally,finalize的区别

final finally finalize
最终的意思。可以修饰:类:不能被继承 变量:常量 方法:不能被重写 是Object类中用于回收垃圾的方法 是异常处理的一部分,用于释放资源

如果catch里面有return语句,finally的代码还会执行吗?如果会,请问是在return前还是return后?

Javase——异常_第10张图片
会执行,在return之前
当代码执行到这一步的时候return a; 在这里返回值其实已经被确定了 555,这里已经不在是return a了,而是return 555. 返回路径已经都形成了,但是发现后面有finally ,所以程序就去执行了finally里面的代码a = 5555. 给a重新赋值了。但是对返回的结果没有影响。 执行完finally里面的代码后,会回到我们之前已经形成的返回路径,把结果返回去。
Javase——异常_第11张图片
如果在finanlly中有return语句,则返回5555

(七) 自定义异常

(1) 为什么要自定义异常

在开发的时候,会有很多自定义的逻辑。很明显java不可能全面考虑到自定义的逻辑的错误。所以需要自定义异常来处理自定义逻辑的错误。

(2) 自定义异常的2种方式

继承Exception: 编译期异常
Javase——异常_第12张图片
继承RuntimeException:运行期异常
Javase——异常_第13张图片

六、异常注意事项

(1) 子类重写父类方法时,子类的方法必须抛出和父类相同的异常或者父类异常的子类。(不能比父类异常大)
(2) 子类重写父类方法时,如果父类抛了多个异常,子类重写父类方法时,也只能抛出相同的异常或者抛出父类异常的子集。不能抛父类没有的异常。
(3) 子类重写父类方法时,如果父类的方法没有抛出异常,子类重写的时候也不能抛出异常。如果子类重写的时候出现了异常,只能在子类方法内部用try…catch处理,不能throws。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号