官术网_书友最值得收藏!

1.3 使用javap查看類文件

前面零星介紹了使用javap來查看類文件,本節將詳細介紹javap命令。由前面的小節也可以看出class文件是二進制塊,想直接與它打交道比較艱難,好在JDK提供了專門用來分析類文件的工具javap以窺探class文件內部的細節。它的使用方式如下:

        javap [options]  <classes>

不加任何參數運行javap的輸出如下所示。

        javap HelloWorld

       Compiled from "HelloWorld.java"
        public class HelloWorld {
          public HelloWorld();
          public static void main(java.lang.String[]);
        }

默認情況下,javap會顯示訪問權限為public、protected和默認級別的方法。如果想要顯示private方法和字段,就需要加上 -p選項。

javap還有一個好用的選項 -s,可以輸出類型描述符簽名信息,HelloWorld.java所有的方法簽名如下所示。

        javap -s HelloWorld

       Compiled from "HelloWorld.java"
        public class HelloWorld {
          public HelloWorld();
            descriptor: ()V

       public static void main(java.lang.String[]);
            descriptor: ([Ljava/lang/String; )V
        }

加上 -c選項可以對類文件進行反編譯,可以顯示出方法內的字節碼,加上 -c選項以后的輸出如下所示。

        javap -c HelloWorld

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

加上 -v選項可以顯示更加詳細的內容,比如版本號、類訪問權限、常量池相關的信息,是一個非常有用的參數,如下所示。

        javap -v HelloWorld

       public class HelloWorld
          minor version: 0
          major version: 52
          flags: ACC_PUBLIC, ACC_SUPER
        Constant pool:
            #1 = Methodref       #6.#15      // java/lang/Object."<init>":()V
            #2 = Fieldref        #16.#17     // java/lang/System.out:Ljava/io/PrintStream;
            ...

還有一個比較少用的 -l選項,可以用來顯示行號表和局部變量表,實測并沒有輸出局部變量表,只顯示了行號表,如下所示。

        javap -l HelloWorld

       public static void main(java.lang.String[]);
        LineNumberTable:
          line 3: 0
          line 4: 8

原因是要想顯示局部變量表,需要在javac編譯的時候加 -g選項,生成所有的調試信息選項,加上 -g選項編譯javac -g HelloWorld.java以后重新執行javap -l命令就可以看到局部變量表(LocalVariableTable)了,如下所示。

        javap -l HelloWorld
        public static void main(java.lang.String[]);
        LineNumberTable:
          line 3: 0
          line 4: 8
        LocalVariableTable:
          Start  Length  Slot  Name    Signature
              0        9      0  args    [Ljava/lang/String;
主站蜘蛛池模板: 靖安县| 尤溪县| 东乡族自治县| 呈贡县| 喀什市| 溧阳市| 东至县| 金山区| 龙南县| 麻阳| 永顺县| 江永县| 广灵县| 青浦区| 伊春市| 宁波市| 光泽县| 开平市| 旬邑县| 孝昌县| 涿鹿县| 姜堰市| 财经| 容城县| 肃宁县| 社旗县| 崇礼县| 南充市| 宣恩县| 望都县| 周宁县| 和田市| 黑河市| 安康市| 五峰| 台湾省| 山东省| 佛教| 同心县| 湖州市| 宁南县|