异常
Exception和Error有什么区别?
在Java中, Throwable
是所有错误或异常的基类。Throwable
又分为Error
和Exception
:
- Exception: 程序本身可以处理的异常,可以通过catch来进行捕获。Exception又可以分为
Checked Exception
(受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)
CheckedException
受检异常:编译器会强制检查并要求处理的异常RuntimeException
运⾏时异常:程序运⾏中出现异常,⽐如我们熟悉的空指针、数组下标 越界等等
- Error :属于程序无法处理的错误,不建议通过catch捕获 。例如Java虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)
try-catch-finally 如何使用?
- try块 : 用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
- catch块 : 用于处理 try 捕获到的异常。
- finally 块 : 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。
我们来看看几个常见的题目:
- 题目(1)
public class TestReflection2 {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
return 1;
} catch (Exception e) {
return 2;
} finally {
System.out.print("3");
}
}
}
结果:31
,在 return 前会先执⾏ finally 语句块,所以是先输出 finally ⾥ 的 3,再输出 return 的 1。
- 题目(2)
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
return 1;
} catch (Exception e) {
return 2;
} finally {
return 3;
}
结果: 3
。 try在return返回前先执⾏ finally,结果 finally 里不按套路出牌,直接 return 了,⾃然也就⾛不到 try ⾥⾯的 return 了 ,注意实际开发中不能在finally中直接return
- 题目(3)
try {
System.out.println("Try to do something");
throw new RuntimeException("RuntimeException");
} catch (Exception e) {
System.out.println("Catch Exception" );
} finally {
System.out.println("Finally");
}
结果:
Try to do something
Catch Exception
Finally
没有return的话,try -catch-finally 依次执行
- 题目(4)
public class TestReflection2 {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 3;
}
}
}
结果:2
, 在执⾏ finally 之前,JVM 会先将 i 的结果暂存起来,然后 finally 执⾏完毕后,会返 回之前暂存的结果,⽽不是返回 i,所以即使 i 已经被修改为 3,最终返回的还是之前暂存起 来的结果 2
- 题目(5)
try {
System.out.println("Try to do something");
throw new RuntimeException("RuntimeException");
} catch (Exception e) {
System.out.println("Catch Exception" );
// 终止当前正在运行的Java虚拟机
System.exit(1);
} finally {
System.out.println("Finally");
}
结果:
ry to do something
Catch Exception
我们可以发现,finally
中的代码一般是一定会执行的,除了 2 种特殊情况下,finally
块的代码也不会被执行:程序所在的线程死亡、关闭 CPU