JAVA class檔案中的符號引用
阿新 • • 發佈:2019-02-01
在java程式碼中,一個類可能使用另外類或者介面的欄位或者呼叫另外一個類的方法。
在編譯的時候,class檔案中是通過叫做"符號引用"的方式來實現的。
如下面的例子
public interface Intf {
public static String str = "abcde";
public static int ival = new Random().nextInt();
}
public class T {
public static int tint = Intf.ival;
}
class T編譯成class 檔案之後,利用javap -verbose 檢視class檔案,可以看到
在初始化static int tint的時候,從常量池的第12項取值
static {};
Code:
Stack=1, Locals=0, Args_size=0
0: getstatic #12; //Field Intf.ival:I
3: putstatic #17; //Field tint:I
6: return
LineNumberTable:
line 6: 0
line 3: 6
常量池的第12項是一個符號引用,指向Intf的ival欄位。ival的值只能在執行的時候才能確定。
const #12 = Field #13.#15; // Intf.ival:I
const #13 = class #14; // Intf
在執行的時候會將符號引用解析為指向Intf記憶體地址的直接引用。
如果將class T改為如下,引用的是Intf的一個在編譯時候就可以確定的常量值。
通過檢視編譯後的class檔案,發現在T的class檔案中,是將str = "abcde";的值
"abcde"直接複製了一份放到了常量池中,沒有符號引用。
public class T {
public static String tstr = Intf.str;
}
在初始化static int tint的時候,從常量池的第12項取值
static {};
Code:
Stack=1, Locals=0, Args_size=0
0: ldc #12; //String abcde
2: putstatic #14; //Field tstr:Ljava/lang/String;
5: return
LineNumberTable:
line 5: 0
line 3: 5
常量池的第12項直接為"abcde"字串。
const #12 = String #13; // abcde
const #13 = Asciz abcde;
在編譯的時候,class檔案中是通過叫做"符號引用"的方式來實現的。
如下面的例子
public interface Intf {
public static String str = "abcde";
public static int ival = new Random().nextInt();
}
public class T {
public static int tint = Intf.ival;
}
class T編譯成class 檔案之後,利用javap -verbose 檢視class檔案,可以看到
在初始化static int tint的時候,從常量池的第12項取值
static {};
Code:
Stack=1, Locals=0, Args_size=0
0: getstatic #12; //Field Intf.ival:I
3: putstatic #17; //Field tint:I
6: return
LineNumberTable:
line 6: 0
line 3: 6
常量池的第12項是一個符號引用,指向Intf的ival欄位。ival的值只能在執行的時候才能確定。
const #12 = Field #13.#15; // Intf.ival:I
const #13 = class #14; // Intf
在執行的時候會將符號引用解析為指向Intf記憶體地址的直接引用。
如果將class T改為如下,引用的是Intf的一個在編譯時候就可以確定的常量值。
通過檢視編譯後的class檔案,發現在T的class檔案中,是將str = "abcde";的值
"abcde"直接複製了一份放到了常量池中,沒有符號引用。
public class T {
public static String tstr = Intf.str;
}
在初始化static int tint的時候,從常量池的第12項取值
static {};
Code:
Stack=1, Locals=0, Args_size=0
0: ldc #12; //String abcde
2: putstatic #14; //Field tstr:Ljava/lang/String;
5: return
LineNumberTable:
line 5: 0
line 3: 5
常量池的第12項直接為"abcde"字串。
const #12 = String #13; // abcde
const #13 = Asciz abcde;
本文的測試是在SUN 的hotspot jvm環境中。
後面這種情況在classpath中甚至可以沒有Intf類檔案。