异常:异常就是代表程序出现问题
异常的继承体系:
Error:严重异常,内存溢出等
其他异常:编译时异常:编译阶段就要进行处理的异常(提醒程序员检查本地信息)
RuntimeException:运行时异常:编译阶段不需要处理,代码运行时出现的异常(代码出错而出现的问题)
简单理解就是编译时异常就是检查你的语法是否错误,运行时异常就是检查你的逻辑是否错误
JVM默认处理异常的方式:
1:把异常的名称,异常原因出现的位置等信息输出到控制台上
2:程序停止执行,异常下面的代码不会再执行了
自己处理异常的方式(捕获异常):
目的:当代码出现异常时,可以让程序继续往下执行
格式:
try{
可能出现异常的代码
}
这个代码会出现什么异常写到catch()里面,如果出现了处理方案是什么写在{}里面
如果出现这个异常会和catch()里面的类型进行对比,如果匹配成功则会捕捉住执行catch里面的代码
catch(异常类名+变量名){
如果出现了处理方案是什么
}
四大问:
1:如果try中没有遇到问题,怎么执行
try里面的代码全部执行完毕,catch里面的代码不会执行(出现了异常并且匹配上了才会执行这里面的代码)
2:如果try中可能会遇到多个问题,怎么执行
写多个catch进行判断,这里有一个弊端,如果这几行代码都有错误,他会只打印第一个错误,然后退出,不会在判断下面的错误
3:如果try中遇到的问题没有被捕获,怎么执行
JVM默认的运行模式
4:如果try中遇到了问题,那么try下面的其他代码还会执行吗
不会执行了,直接匹配catch里面的代码,如果匹配不上就执行jvm默认的异常
总结:try里面的代码如果没有问题则会全部执行,不会执行catch里面的代码,然后程序会继续执行 try-catch
结构之后的代码,如果有问题则会中断try里面的代码,则会匹配catch里面的代码并执行,然后程序会继续执行 try-catch
结构之后的代码,如果有问题匹配不上catch里面的代码则会JVM默认处理结束程序,不会执行 try-catch
结构之后的代码
异常中的常见方法:
getMessage:打印异常信息
toString:打印异常名字和信息
prinStackTrace:打印异常名字和异常信息和异常的地方
快捷方式:ctrl+alt+t,IDEA自动生成代码
throw和throws:
代码解释:
-
JVM 自动创建
ArrayIndexOutOfBoundsException
异常对象并抛出 -
test
方法未捕获异常,异常对象沿调用栈向上传递到main
方法。 -
main
方法中也没有try-catch
块处理该异常,因此异常继续向上抛出。 -
当异常传递到最顶层的
main
方法仍未被捕获时,JVM 接管处理: -
终止程序,后续代码(如果有)不会执行。
-
打印异常堆栈信息(包括异常类型、错误描述及调用路径)。
代码解释:
-
JVM 自动创建
ArrayIndexOutOfBoundsException
异常对象并抛出 -
test
方法未捕获异常,异常对象沿调用栈向上传递到main
方法。 -
main
方法中有try代码块并进行catch匹配捕捉,捕捉到之后执行catch里面的代码,执行完之后接着执行try-catch
结构之后的代码
代码解释:
throw是把异常返回到调用处
-
test(s)
调用test
方法接收数组i
(长度为 5),进入if (i.length <= 5)
条件- 条件成立,显式创建
ArrayIndexOutOfBoundsException
对象并通过throw
抛出
-
异常传递
throw
会立即中断test
方法的执行,将异常对象传递到调用者main
方法
-
catch
块的匹配与捕获main
方法中的catch (ArrayIndexOutOfBoundsException e)
匹配该异常类型,捕获异常对象e
-
后续代码执行
- 由于异常被捕获,程序继续执行
System.out.println(Arrays.toString(s))
,输出数组内容[1, 2, 3, 4, 5]
- 由于异常被捕获,程序继续执行
自定义异常:
1:定义异常类
2:写继承关系(看这个异常类属于哪个(运行或者异常))
3:空参构造
4:带参构造
解释:
类的名字就是异常的名字
空参或者带参构造就是异常的信息
、
注意:
编译时异常必须处理否则报错
运行时异常不用必须处理最后会由jvm接管