❤️ 异常体系
- 非检查型异常 = error + RuntimeException、检查型异常 = 非 RuntimeException
- error 是专门为 JVM 设计的,我们不应该去使用
RuntimeException运行时异常getMessage()返回此异常的详细信息字符串toString()返回简短的异常类名 + 异常原因printStackTrace()输出异常错误信息到控制台【异常类名 + 位置 + 原因】
非RuntimeException编译时异常,在写的时候已经有红线提示了,必须被 throw,或者 try…catch…(算是给用户一个 warn,你必须要对这个异常有所处理)

JVM 会自己默认处理异常,那我们为什么还要自己处理呢?
因为 JVM 的默认处理方案会终止程序的运行,但我们在实际开发中就算程序出错了,我们依然还要继续运行
❤️ 异常处理
💛 try…catch…
java
try {
可能出现异常的代码
……
} catch(异常类名,变量名) {
异常处理的代码
……
}
……
ANOTE
- try 住的代码块要尽可能的小,因为 JVM 不会对 try 住的代码进行优化~~【重排序、内联】~~,怕导致不可预知的结果
- 一般不会 try 住 throwable 异常,因为里面包含了 error (不是程序代码能处理的),除非是对于将本服务器的请求委托给外部时,由于外部可能会抛出 error 级别的异常,如果我们不 catch 一个 throwable,会导致我们的服务也崩溃
执行流程 :
- 执行 try 内的代码
- 未出现异常,不执行 catch 内的代码
- 出现异常
- 生成一个异常类对象,该对象被提交给 Java 运行时系统
- Java 运行时系统到 catch 中匹配异常类,匹配成功,则执行 catch 内代码
- 接着继续向下执行,直到代码 A
[!hint] 经典案例
- for 循环里面 try …… catch ……,如果 try 里面报错,for 循环继续执行
- try 里面 for 循环,如果 try 里面报错,for 循环会终止
💛 try…finally…
- 不要在 finally 块中 return,而且会导致 catch 块的异常不会被处理
java
public int testMethod() {
try {
return 1; // 这里返回1
} finally {
return 2; // 但是最终返回的是2
}
}💛 try(resource) …… catch ……
resource 的代码会在 try 语法块执行完毕后,自动释放资源
java
try (ResourceType resource = new ResourceTypeConstructor()) {
// 使用 resource 的代码块
} catch (ExceptionType e) {
// 异常处理代码
}💛 throws
throws 仅仅是抛出异常,并没有做任何处理,如果异常一直抛到了主程序,那程序就会崩溃,但是如果异常被 throw 了,但是在某个地方被 catch 了,那程序就不会崩溃
java
public void method() throws 异常名 {
……
}❤️ 自定义异常
java
public class demo {
// 异常类
static class scoreException extends Exception {
// 无参构造
public scoreException() {}
// 带参构造
public scoreException(String message) {
// 传给Exception,Exception传给Throwable中的detailMessage
super(message);
}
}
public static void main(String[] args) throws scoreException {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
if (i < 0 || i > 100){
throw new scoreException("你输入的分数有误");
}else {
System.out.println("分数正常");
}
}
}❤️ 使用异常
- 如果用户对于异常无能为力(只能 throw、或者打印异常信息 ……),那 api 的设计者应该将这个异常设置为运行时异常 RuntimeException,无需强制用户处理
- 非检查型异常用户无需进行捕获,也不应该捕获
❤️ 异常大全
💛 注释异常
java
System.out.println("bug"); //\u000A is a newline
---
java: 需要';'由于注释里的\u000A导致的,因为读程序时\u000A 会转换为一个换行符
java
System.out.println("bug"); //look inside c:\users
---
非法的Unicode转义由于\u 后面没有跟着 4 位的十六进制数