關于java中final變量的小問題
最近看了關于java語言規范中關于final變量的介紹,一直很好奇為什么final定義的字段是jvm內部是如何處理的,今天寫了一個測試類,看看用javac編譯器編譯出來的java class 字節碼,以便連接final變量在jvm運行時候如何保證final變量的不變性。
java class定義如下
public class FinalVarClass {
public void test(){
final int a=1;
int b=a;
System.out.println(a);
}
}
用javac 編譯器進行編譯(jdk版本1.6 ,操作系統 mac os x),用javap 進行字節碼解析出來的結果如下
{
public FinalVarClass();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LFinalVarClass;
public void test();
Code:
Stack=2, Locals=3, Args_size=1
0: iconst_1
1: istore_1
2: iconst_1
3: istore_2
4: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
7: iconst_1
8: invokevirtual #21; //Method java/io/PrintStream.println:(I)V
11: return
LineNumberTable:
line 5: 0
line 6: 2
line 7: 4
line 8: 11
LocalVariableTable:
Start Length Slot Name Signature
0 12 0 this LFinalVarClass;
2 10 1 a I
4 8 2 b I
}
在code里面,首先對final變量a進行賦值為1,以后對a的處理,直接轉化為對常量1的操作。javac編譯器編譯出來的字節碼中把所有對a的訪問,轉化為對常量1的操作。在字節碼這一層直接進行的轉化。
思考:是不是可以通過修改字節碼,人為的對a進行再次賦值
實際上java語言設計者已經考慮到這個問題了,所以jvm在加載class文件的時候,會有一個校驗過程,專門有次校驗的。
浙公網安備 33010602011771號