Java异常
异常就是程序在编译和运行时出现的不正常情况
通过面向对象的编程思想将异常进行封装,以Java类的形式对其描述
Java异常结构
Throwable是异常超类
Error、Exception是Throwable的子类
RuntimeException、非RuntimeException是Exception的子类
Error 错误类
表示JVM的错误,会导致JVM无法继续执行,程序中无法解决
不可捕捉,只能显示错误信息
一般出现这种错误,只能尽力使得程序安全退出
Exception 异常类
表示可恢复的异常,可以在程序中解决
分为运行时异常,非运行时异常
1)RuntimeException:在编译期不检查,出现问题后,需要我们回来修改代码
运行程序过程中报出的异常,比如被除数为0 (被除数为0的结果是无穷大,对于计算机来说无穷大会把内存跑满)
2)非RuntimeException:编译期就必须处理的,否则程序不能通过编译,就更不能正常运行了
不解决无法运行程序,比如语法错误
JVM处理异常的方式
如果程序出现了问题,JVM会做默认的处理
-
把异常的名称,错误原因及异常出现的位置等信息输出在控制台
-
程序终止
异常处理的语法
try {
可能出现异常的代码段;
} catch(异常类名1 变量名) {
异常的处理代码;
} catch(异常类名2 变量名) {
异常的处理代码;
}finally {
无论try...catch语句如何执行,finally语句一定会被执行
}
执行流程
1)程序从 try 里面的代码开始执行
2)出现异常,就会跳转到对应的 catch 里面去执行
3)不管程序是否遇到异常,执行完毕之后,程序都需要执行finally的代码
4)若没有finally,执行完catch后也会继续往下执行
即加入异常捕获机制,不会让代码执行终止
finally作为异常的统一出口,在此语句块的编写中尽可能不要出现throw和return这样的语句
Throwable类的常用方法
public String getMessage() 返回此 throwable 的详细消息字符串
public String toString() 返回此可抛出的简短描述
public void printStackTrace() 把异常的错误信息输出在控制台,常用
编译时异常和运行时异常的区别
1)编译时异常
无法通过编译,如语法错误
2)运行时异常
无法继续执行,如除数为0
throw和throws方式处理异常
1)throws
写在方法后面,直接抛出异常,表示该异常不在此方法中处理,会在调用该方法的地方做处理
public void fun() throws Exception
2)throw
写在方法体中,一般直接抛出异常
throw new Exception();
throws与throw区别:
1、 throws用在方法声明后面,throw用在方法体内
2、 throws表示抛出异常,由该方法的调用者来处理异常
throw表示在方法体内抛出异常,由该方法处理
3、 throws表示异常的一种可能性,并不一定会发生这个异常
throw执行了就会抛出该异常
Java的异常处理机制
在整个Java的异常处理中,实际上也是按照面向对象的方式进行处理
1、 一旦产生异常,会产生一个异常类的实例化对象
2、 在try语句中对此异常对象进行捕获
3、 产生的异常对象会与catch语句中的各个异常类型进行匹配,如果匹配成功,则执行catch语句中的代码
注意,异常类也会有父子关系,子类异常实例可以被父类异常类接收,这里类似于向上转型,即所有异常类都会被Exception接收
注意,在Java中,所有捕获范围小的异常必须放在捕获范围大的异常之前,否会程序在编译时会出现问题
自定义异常类
Java中有很多预定义的异常类,开发也可以根据自己的业务自定义异常类
定义异常类只需要继承Exception类即可
定义异常类时通常需要提供两个构造器:
一个是无参数的 构造器;
另一个是带个字符串参数的构造器,这个字符串将作为该异常对象的描述信息(也就是异常对象的getMessage()方法的返回值)。
public class MyException extends Exception {
public MyException() {
}
public MyException(String msg) {
super(msg);
}
}
public static void main(String[] args) {
try {
throw new MyException("这是自定义的异常");
} catch (MyException e) {
e.printStackTrace();
}
}