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;
...
}
}
}