【1】异常的划分
1)按继承体系划分:分为两个子类,一个是ERROR(错误),另一个是Exception(异常)
错误属于比较严重的,异常属于可以恢复的错误。
2)按检查和未检查划分:分为检查异常(蓝色方框)和未检查异常(红色方框)。
区别:检查异常需要配合try-catch或throws关键字一起使用, 否则会引起编译错误。
未检查异常:用不用关键字都可以。
【2】异常的语法
1)积极处理
try{
可能引发异常的语句
}catch(Exception){
捕捉到的异常信息
}finally{-----无论上面的catch是否能捕捉到真正的异常,都会执行的语句(这步操作根据需求添加)
一定会执行的语句
}
简单的理解:try中的语句就是可能会引起异常,而异常会导致程序中止,如果catch可以捕捉到上述的异常,那么就可以使程序正常运行。*不管是否捕捉到对应的异常,finally中的语句都是要执行的。*
特殊的4种情况,finally语句块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中使用了System.exit()退出程序。
3)程序所有的线程死亡。
4) 关闭CPU。
当然一个try后面可以跟上多个catch语句,这些catch中的内容是并列的或是继承关系。如果是继承关系,需注意父类不能写在子类的前面。
2)消极处理
给出throws。
如果语句中存在异常,没有try-catch关键字,那么异常发生时,会将异常传递给方法的调用者,这时候需要在方法声明上抛出异常。
如果方法中出现的的是检查异常,则必须给出throws,如果是未检查异常,则可以给也可以不给。
【3】异常的常用方法
getMessage()---返回的是异常的信息
getStackTrace()---打印异常的跟踪信息
创建异常类:
1)class MyException extends Exception{ // 检查异常 }
2)class MyException extends RuntimeException { // 未检查异常}
【4】自定义异常
步骤:
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常
- 如果在当前抛出的异常方法中处理异常,可以使用try-catch语句块捕获并处理,否则在方法的声明处通过throws关键字指名要抛出给方法调用者的异常,继续下一操作。
- 在出现异常方法的调用者中捕获并处理异常。
【5】在方法中抛出异常
如果某个方法可能发生异常,但又不想立刻处理,则可以使用throws或者throw关键字在方法中抛出异常,但最终要有能够处理该异常的代码。
- throws通常被应用在声明方法时。多个异常可使用逗号分隔。
- RuntimeException、Error或是他们的子类,可以不使用throws关键字抛出异常,编译仍能通过,但在运行时会被系统抛 出。
- throw关键字用于方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即终止,后面语句不执行。通过throw抛出异常后,若想在上一级代码中捕获并处理异常,则需要在抛出的异常方法中使用throws在方法声明中指明要抛出的异常;如果要捕捉throw抛出的异常,必须使用try-catch语句块。
- throw通常用来抛出用户自定义异常。
【6】异常的注意事项
- 方法重写---子类方法不能比父类抛出更多的异常,子类重写的方法可以不抛出。
- 将检查异常包装为未检查异常。(建议)
- 不要吞异常---即catch块后面什么也不写,这样即使将来产生异常,也不知道是什么异常。
- 如果try,catch,finally中都有return以finally中的为准 如果try中有return,即使finally对return后的值做了改动,也不会影响 到返回后的结果。
- 在调用方法时,方法的类型不为void,则在try块和catch块中,都需要加入return(前提,不存在finally中的returun)
- 当调用的方法出现检查异常或自定义异常,则在调用时,如果使用try-catch(积极处理),则可以正常使用,不用一级一级的向上抛出;如果使用throws(消极处理),则必须一级一级的向上抛出。---如果为未检查异常,则不需要加以处理。
- 如果catch捕获的异常不完整,则编译不会通过。
- 异常产生后,如果不做任何处理,程序就会被终止。
- 一个方法被覆盖时覆盖它的方法必须抛出相同的异常或异常的子类。如果父类抛出多个子类,则覆盖方法必须抛出那些异常的子类,不能抛出新的异常。
- 与有返回值的方法连用时要注意:
public class Exception5 {
public static int test(){
try {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int r = 1/n;
return r;
} catch (Exception e ) {
System.out.println(e.getMessage());
return -1; // 解决方法1: 在catch也写一个return返回结果
// throw e; // 解决方法2: 把异常重新抛出
}
}
public static void main(String[] args) {
int r = test();
System.out.println(r);
}
}
【7】常见的异常
- 数组下标越界--->ArrayIndexOutOfBoundsException
- 访问null的对象的方法或属性(空指针异常)--->NullPointerException
- 类型转换异常--->ClassCastException
- 未找到相应类异常--->ClassNotFoundException
- 遍历集合的同时remove--->ConcurrentModificationException(并发修改异常)
- 算术异常(除零)--->ArithmeticException
- 在堆内存耗尽时--->OutOfMemoryError(new的太多了)
- 在栈内存耗尽时--->StackOverflowError(应用程序递归太深而发生堆栈溢出)
- 数组中包含不兼容的值抛出的异常--->ArrayStoreException
- 操作数据库异常类--->SQLException
- 字段未找到异常--->NoSuchFieldException
- 方法未找到抛出的异常--->NoSuchMethodException
- 字符串转化为数字异常--->NumberFormatException
- 数组元素为负数抛出的异常--->NegativeArraySizeException
- 字符串索引超出范围--->StringIndexOutBoundsException
- 输入输出异常--->IOExceotion
- 不允许访问某类异常--->IllegalAccessException
- 文件已结束异常--->EOFException
- 文件未找到异常--->FileNotFoundException
好长时间没做过总结了,感觉总结还是很重要的,总结的时候会搞清楚很多东西,还会给杂乱的知识框架化。。。希望诸位学习完之后也做做总结。
日常鸡汤:你的人生永远不会辜负你就自己,那些走错的路
全都会让你成为独一无二的自己。。。