標籤:mod object tail 不同 [] stat strong public ESS
常量是程式運行期間恒定不變的量,許多程式設計語言都有某種方式,向編譯器告知一塊資料是恒定不變的,例如C++中的const和Java中的final。
根據編譯器的不同行為,常量又分為編譯時間常量和運行時常量,其實編譯時間常量肯定就是運行時常量,只是編譯時間常量在編譯的時候就被執行計算,並帶入到程式中一切可能用到它的計算式中。
以Java為例,static final int a = 1將是一個編譯時間常量,編譯後的符號表中將找不到a,所有對a的引用都被替換成了1。
而static final int b = “”.length()將是一個運行時常量。測試代碼如下:
class Test { public static final int a = 10; public static final int b = "test".length(); static { System.out.println("Class Test Was Loaded !"); }}public class CompilConstant { public static void main(String[] args) { System.out.println(Test.a); System.out.println(Test.b); }}
輸出:
10Class Test Was Loaded !4
即:
1. a被作為編譯期全域常量,並不依賴於類,而b作為運行期的全域常量,其值還是依賴於類的。
2. 編譯時間常量在編譯時間就可以確定值,上例中的a可以確定值,但是b在編譯期是不可能確定值的。
3. 由於編譯時間常量不依賴於類,所以對編譯時間常量的訪問不會引發類的初始化。
測試:
//System.out.println(Test.b);//注釋掉該條代碼
執行
javac CompilConstant.javadel Test.class
也就是把編譯產生的Test.class 刪除,並執行java CompilConstant,輸出:
10
執行反組譯碼:
javap -v CompilConstant
D:\N3verL4nd\Desktop>javap -v CompilConstantClassfile /D:/N3verL4nd/Desktop/CompilConstant.class Last modified 2017-10-21; size 440 bytes MD5 checksum faf8cf7e41ff58ae190d78fbb7e7635c Compiled from "CompilConstant.java"public class CompilConstant minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #7.#16 // java/lang/Object."<init>":()V #2 = Fieldref #17.#18 // java/lang/System.out:Ljava/io/PrintStream; #3 = Class #19 // Test #4 = Methodref #20.#21 // java/io/PrintStream.println:(I)V #5 = Fieldref #3.#22 // Test.c:I #6 = Class #23 // CompilConstant #7 = Class #24 // java/lang/Object #8 = Utf8 <init> #9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 main #13 = Utf8 ([Ljava/lang/String;)V #14 = Utf8 SourceFile #15 = Utf8 CompilConstant.java #16 = NameAndType #8:#9 // "<init>":()V #17 = Class #25 // java/lang/System #18 = NameAndType #26:#27 // out:Ljava/io/PrintStream; #19 = Utf8 Test #20 = Class #28 // java/io/PrintStream #21 = NameAndType #29:#30 // println:(I)V #22 = NameAndType #31:#32 // b:I #23 = Utf8 CompilConstant #24 = Utf8 java/lang/Object #25 = Utf8 java/lang/System #26 = Utf8 out #27 = Utf8 Ljava/io/PrintStream; #28 = Utf8 java/io/PrintStream #29 = Utf8 println #30 = Utf8 (I)V #31 = Utf8 b #32 = Utf8 I{ public CompilConstant(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 9: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: bipush 10 5: invokevirtual #4 // Method java/io/PrintStream.println:(I)V 8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 11: getstatic #5 // Field Test.b:I 14: invokevirtual #4 // Method java/io/PrintStream.println:(I)V 17: return LineNumberTable: line 11: 0 line 12: 8 line 13: 17}SourceFile: "CompilConstant.java"D:\N3verL4nd\Desktop>
可見,對於Test.a的輸出直接把bipush 10 10壓入棧中。
轉載自 :N3verL4nd 出處: 78303623
java中的編譯時間常量與運行時常量