Đúng, như những người khác đã nói, một try
khối ức chế một số tối ưu hóa trên các {}
nhân vật xung quanh nó. Cụ thể, trình tối ưu hóa phải cho rằng một ngoại lệ có thể xảy ra tại bất kỳ điểm nào trong khối, vì vậy không có gì đảm bảo rằng các câu lệnh được thực thi.
Ví dụ:
try {
int x = a + b * c * d;
other stuff;
}
catch (something) {
....
}
int y = a + b * c * d;
use y somehow;
Nếu không có try
, giá trị được tính để gán cho x
có thể được lưu dưới dạng "biểu thức con chung" và được sử dụng lại để gán cho y
. Nhưng do try
không có gì đảm bảo rằng biểu thức đầu tiên đã được đánh giá, nên biểu thức phải được tính toán lại. Đây thường không phải là một vấn đề lớn trong mã "đường thẳng", nhưng có thể có ý nghĩa trong một vòng lặp.
Tuy nhiên, cần lưu ý rằng điều này chỉ áp dụng cho mã JITCed. javac chỉ thực hiện một lượng tối ưu hóa nhỏ và không có chi phí nào cho trình thông dịch mã byte để nhập / rời một try
khối. (Không có mã byte được tạo để đánh dấu các ranh giới khối.)
Và cho bestsss:
public class TryFinally {
public static void main(String[] argv) throws Throwable {
try {
throw new Throwable();
}
finally {
System.out.println("Finally!");
}
}
}
Đầu ra:
C:\JavaTools>java TryFinally
Finally!
Exception in thread "main" java.lang.Throwable
at TryFinally.main(TryFinally.java:4)
đầu ra javap:
C:\JavaTools>javap -c TryFinally.class
Compiled from "TryFinally.java"
public class TryFinally {
public TryFinally();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Throwable;
Code:
0: new #2 // class java/lang/Throwable
3: dup
4: invokespecial #3 // Method java/lang/Throwable."<init>":()V
7: athrow
8: astore_1
9: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
12: ldc #5 // String Finally!
14: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
17: aload_1
18: athrow
Exception table:
from to target type
0 9 8 any
}
Không có "GOTO".