参考 《Java核心技术 卷1》
1. try - catch - finally 语法
try {
// 1
code that might throw exceptions
// 2
} catch (IOException e) {
// 3
show error message
// 4
} finally { // 关闭资源
// 5
in.dose();
}
// 6
-
finally 语句
- 不管异常是否被捕获,finally 子句中的代码都会执行;
- 通常,在 finally 子句中编写一些关闭资源的代码。
2. try - catch - finally 执行顺序(3 种情况)
2.1. 代码没有抛出异常。
- 此时,首先执行
try
中所有代码,然后执行finally
语句中的所有代码。最后,执行finally
语句块后面的第一条语句。 - 执行顺序为:1、2、5、6 (对应上面语法中的 语句块)
栗子 🌰
class Solution {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
System.out.println("try before...");
// int i = 1 / 0;
System.out.println("try after...");
// return 0;
} catch (Exception e) {
System.out.println("catch before...");
e.printStackTrace();
System.out.println("catch after...");
} finally {
System.out.println("finally...");
// return -1;
}
System.out.println("end..");
return 1;
}
}
2.2. 代码抛出异常,并在一个 catch
子句中捕获
- 此时,首先执行
try
中代码,直到抛出异常为止,接着跳过try
语句块中剩余的代码。 - 然后去匹配
catch
子句(此时,分为两种情况),最后执行finally
语句中的所有代码。- Case1:如果
catch
子句没有抛出异常, 程序将执行try
语句块之后的第一条语句;- 执行顺序:1、3、4、5、6
- Case2:如果
catch
子句抛出了一个异常,异常将被抛回到这个方法的调用者。- 执行顺序:1、3、5
- Case1:如果
Case1
class Solution {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
System.out.println("try before...");
int i = 1 / 0;
System.out.println("try after...");
// return 0;
} catch (Exception e) {
System.out.println("catch before...");
e.printStackTrace();
System.out.println("catch after...");
} finally {
System.out.println("finally...");
// return -1;
}
System.out.println("end..");
return 1;
}
}
Case2
class Solution {
public static void main(String[] args) throws Exception {
System.out.println(test());
}
public static int test() throws Exception {
try {
System.out.println("try before...");
int i = 1 / 0;
System.out.println("try after...");
// return 0;
} catch (Exception e) {
System.out.println("catch before...");
e.printStackTrace();
throw new Exception();
// System.out.println("catch after...");
} finally {
System.out.println("finally...");
// return -1;
}
System.out.println("end..");
return 1;
}
}
2.3. 代码抛出异常,但没有在任何一个 catch
子句中捕获
- 此时,首先执行
try
中代码,直到抛出异常为止,此时跳过try
语句块中剩余的代码。 - 然后,执行
finally
语句中的所有代码,并将异常抛回给这个方法的调用者。 - 执行顺序:1、5
栗子 🌰
class Solution {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
System.out.println("try before...");
int i = 1 / 0;
System.out.println("try after...");
// return 0;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("catch before...");
e.printStackTrace();
System.out.println("catch after...");
} finally {
System.out.println("finally...");
// return -1;
}
System.out.println("end..");
return 1;
}
}
可以只有 try - finally.
finally 包含改变控制流的语句
-
当
finally
子句包含return
语句时,可能会造成方法无法返回正常值。 -
如果
try
语句块中有return
语句,但在方法真正返回前会执行finally
子句块。此时,如果finally
块中也有一个return
语句,则finally
中的这个返回值会覆盖掉原来try
中的返回值。
Case1:try
有 return、finally
无 return
当 try
中有 return 语句,finally
中无 return 语句,且没有异常时,执行顺序为:
- 首先,执行try 中return之前的代码;
- 然后,执行finally中的代码块;
- 最终,执行try 中的return语句。
class Solution {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
System.out.println("try before...");
// int i = 1 / 0;
System.out.println("try after...");
return 0;
} catch (Exception e) {
System.out.println("catch before...");
e.printStackTrace();
System.out.println("catch after...");
} finally {
System.out.println("finally...");
// return -1;
}
System.out.println("end..");
return 1;
}
}
Case2:try
、finally
都有 return
当 try
、finally
都有 return 时,finally
中的 return 语句会覆盖 try
中的 return 语句。
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
System.out.println("try before...");
// int i = 1 / 0;
System.out.println("try after...");
return 0;
} catch (Exception e) {
System.out.println("catch before...");
e.printStackTrace();
System.out.println("catch after...");
} finally {
System.out.println("finally...");
return -1;
}
// System.out.println("end..");
// return 1;
}
}
注意⚠️:不要把改变控制流的语句(return,throw,break,continue)放在 finally 子句中。