Java虛擬機(三)------常量的本質含義與反編譯及助記符詳解

-XX:+TraceClassLoading,用於追蹤類的加載信息並打印出來
jvm參數-XX:+,表示開啓option參數
-XX:-,b表示關閉option參數
-XX:=,b表示將option選項的值設置爲value

 package com.huawei.jvm.classloader;

public class MyTest2 {
    public static void main(String[] args) {
        System.out.println(MyParent2.str);
    }

}
class MyParent2{
    public static  final  String str = "hello world";
    static {
        System.out.println("MyParent2 static block");
    }
}
輸出結果:hello world


 package com.huawei.jvm.classloader;

public class MyTest2 {
    public static void main(String[] args) {
        System.out.println(MyParent2.str);
    }

}
class MyParent2{
    public static String str = "hello world";
    static {
        System.out.println("MyParent2 static block");
    }
}
 輸出結果:MyParent2 static block
		 hello world

常量在編譯階段會被存入到調用這個常量的方法所在的類的常量池中
本質上調用類並沒有直接引用,因此並不會觸發定義常量的類的初始化
這裏指的是將常量存放到了MyTest2的常量池中,之後MyTest2與MyParent2就沒有任何關係了
甚至,我們可以將MyParent2的class文件刪除

反編譯

    javap -c com.huawei.jvm.classloader.MyTest2
Compiled from "MyTest2.java"
public class com.huawei.jvm.classloader.MyTest2 {
  public com.huawei.jvm.classloader.MyTest2();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #4                  // String hello world
       5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

助記符:

ldc表示int,float或String類型的常量值從常量池中推送至棧頂
binpush表示將單字節(-128-127)的常量值推送至棧頂
xipush表示將一個短整形常量值(-32768-2767)推送至棧頂
iconst_1表示將int類型1推送至棧頂(iconst_1-iconst_5)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章