Theo cách hiểu thông thường thì khi gặp return thì method kết thúc và trở về calling method.
Nhưng gặp finally của exception thì nó chạy khác:
public class Example {
public int foo() {
try {
System.out.println("foo(): try block"); // 1.1
return 1; // 1.2
} finally {
System.out.println("foo(): finally block"); // 1.3
}
}
public int bar() {
try {
System.out.println("bar(): try block"); // 2.1
return 1; // 2.2
} finally {
System.out.println("bar(): finally block"); // 2.3
return 2; // 2.4
}
}
}
Về Example.foo(), nó sẽ chạy thêm 1 lệnh trong finally: 1.1 -> 1.2 (return) -> 1.3.
Method thông thường thì chỉ chạy 2 lệnh, đến lệnh return ở 1.2 là dừng, nhưng với foo() có finally nên phải chạy thêm 1.3 nữa.
Còn Example.bar(), thứ tự chạy:
- 2.1 -> 2.2 (return) -> 2.3 -> 2.4 (return)
Ngoài chạy thêm 2 lệnh trong finally sau 2.2, method còn bỏ luôn giá trị trả về của 2.2 mà chỉ lấy giá trị return của 2.4. Như trong method bar(), giá trị trả về sẽ là 2 thay vì là 1.
Và khó khăn hơn là khi có luôn cả catch và finally, return nào bị bỏ qua? (return trong try? hay bỏ return trong catch?)
class Example {
public int call() {
try {
if (...) throw new Ex1(...);
if (...) throw new Ex2(...);
...
return 1;
catch (Ex1 e) {
...
return 2;
catch (Ex2 e) {
...
return 3;
}
...
finally {
...
if (...) return -1;
...
}
}
}