目录介绍
- 1.什么是异常
-
2.异常
- 2.1 异常的概述和分类【了解】
- 2.2 JVM默认是如何处理异常的【理解】
- 2.3 异常处理的两种方式【理解】
- 2.4 try...catch的方式处理异常【掌握】
- 2.5 编译期异常和运行期异常的区别【理解】
- 2.6 throw的概述以及和throws的区别【掌握】
- 2.7 异常的注意事项及如何使用异常处理【了解】
- 2.8 Throwable类中的常用方法
- 3.Error(错误)
- 4.Exception(异常)
-
5.处理异常机制深入理解
- 5.1 抛出异常
- 5.2 捕获异常
- 5.3 异常处理方式不同
-
6.异常总结
- 6.1 异常总结
- 6.2 try-catch-finally规则
- 6.3 try、catch、finally语句块的执行顺序
- 6.4 Throws抛出异常的规则
- 7.自定义异常
好消息
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong211/YCBlogs
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!
0.异常思维导图
![image image]()
1.什么是异常
-
1.1 什么是异常?
- 异常是正常程序流程所不能处理或者没有处理的异常情况或异常事件,比如算术运算被0除,数组下标越界等。
- Java采用try-catch-finally语句捕获并处理异常并且处理异常。
-
1.2 finally一定会执行吗
- finally是异常处理的统一出口,常用来实现资源释放,比如关闭文件,关于数据库连接等。除非遇到System.exit()强制退出程序外,finally语句块无论是否发生异常都要执行。
2.异常
-
2.1 异常的概述和分类
- A:异常的概述: 异常就是Java程序在运行过程中出现的错误。
- B:异常的分类:
-
C:异常的继承体系
- 异常的基类: Throwable
- 严重问题: Error 不予处理,因为这种问题一般是很严重的问题,比如: 内存溢出
-
非严重问题: Exception
- 编译时异常: 非RuntimeException
- 运行时异常: RuntimeException
-
2.2 JVM默认是如何处理异常的【理解】
-
JVM默认是如何处理异常的
-
main函数收到这个问题时,有两种处理方式:
- a:自己将该问题处理,然后继续运行
- b:自己没有针对的处理方式,只有交给调用main的jvm来处理
- jvm有一个默认的异常处理机制,就将该异常进行处理.
- 并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上,同时将程序停止运行
-
2.6 throw的概述以及和throws的区别【掌握】
- throws的方式处理异常: 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。
- throw的概述: 在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
-
a:throws
- 用在方法声明后面,跟的是异常类名
- 可以跟多个异常类名,用逗号隔开
- 表示抛出异常,由该方法的调用者来处理
- throws表示出现异常的一种可能性,并不一定会发生这些异常
static void pop() throws NegativeArraySizeException {
// 定义方法并抛出NegativeArraySizeException异常
int[] arr = new int[-3]; // 创建数组
}
public static void main(String[] args) { // 主方法
try { // try语句处理异常信息
pop(); // 调用pop()方法
} catch (NegativeArraySizeException e) {
System.out.println("pop()方法抛出的异常");// 输出异常信息
}
}
使用throws关键字将异常抛给调用者后,如果调用者不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的调用者。
pop方法没有处理异常NegativeArraySizeException,而是由main函数来处理。
-
b:throw
- 用在方法体内,跟的是异常对象名
- 只能抛出一个异常对象名
- 表示抛出异常,由方法体内的语句处理
public PlayService getPlayService() {
PlayService playService = BaseAppHelper.get().getPlayService();
if (playService == null) {
//待解决:当长期处于后台,如何保活?避免service被杀死……
throw new NullPointerException("play service is null");
}
return playService;
}
-
2.7 异常的注意事项及如何使用异常处理【了解】
-
A:异常注意事项(针对编译期异常)
- a:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
- b:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
- c:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
-
B:如何使用异常处理
- 原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws
-
区别:
- 后续程序需要继续运行就try
- 后续程序不需要继续运行就throws
- 如果JDK没有提供对应的异常,需要自定义异常。
2.8 Throwable类中的常用方法
3.Error(错误)
- Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
4.Exception(异常)
5.处理异常机制深入理解
5.1 抛出异常
- 当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。
5.2 捕获异常
- 在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适 的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适 的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。
5.3 异常处理方式不同
6.异常总结
6.1 异常总结
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
6.2 try-catch-finally规则
1) 必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。
2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。
3) catch 块与相应的异常类的类型相关。
4) 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块
5) 可嵌套 try-catch-finally 结构。
6) 在 try-catch-finally 结构中,可重新抛出异常。
7) 除了下列情况,总将执行 finally 做为结束:JVM 过早终止(调用 System.exit(int));在 finally 块中抛出一个未处理的异常;计算机断电、失火、或遭遇病毒攻击。
6.3 try、catch、finally语句块的执行顺序
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
6.4 Throws抛出异常的规则
1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误
3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。
7.自定义异常
关于其他内容介绍
01.关于博客汇总链接
02.关于我的博客