1. try - catch - finally 语法参考 《Java核心技术 卷1》
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
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;
}
}
finally 包含改变控制流的语句可以只有 try - finally.
当 finally 子句包含 return 语句时,可能会造成方法无法返回正常值。
如果 try 语句块中有 return 语句,但在方法真正返回前会执行 finally 子句块。此时,如果 finally 块中也有一个 return 语句,则 finally 中的这个返回值会覆盖掉原来 try 中的返回值。
Case1:try 有 return、finally 无 returnclass 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
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 子句中。



