JVM学习-javap解析Class文件

JVM学习-javap解析Class文件

码农世界 2024-05-28 前端 70 次浏览 0个评论
解析字节码的作用
  • 通过反编译生成字节码文件,可以深入了解Java工作机制,但自己分析类文件结构太麻烦,除了第三方的jclasslib工具外,官方提供了javap
  • javap是jdk自带的反解析工具,它的作用是根据class字节码文件,反解析出当前类对应的code区(字节码指令)、局部变量表、异常表、代码行偏移量映射表、常量池等信息
  • 通过局部变量表,可以查看局部变量的作用域范围、所在槽位等信息,甚至可以看到槽位复用信息
    java -g操作
    • 解析字节码文件得到的信息中,有些信息(如局部变量表、指令和代码行偏移量映射表、常量池中方法的参数名称等)需要在使用javac编译成class文件时,指定参数才能输出
    • 直接使用javac xx.java,不会生成对应局部变量表等信息,使用javac -g xx.java可以生成相关信息,如使用eclipse或IDEA,默认情况下,在编译时会帮你生成局部变量表,指令和代码偏移量映射表等信息
      javap
      • 格式 javap
        • classes是要反编译的class文件
        • 在命令行直接输入javap或javap -help可以看到javap的options有如下选项

          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -version JavapTest.class
          1.8.0_131
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
            int getNum(int);
            protected char showGender();
            public void showInfo();
            static {};
          }
          // -public 显示公共信息
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -public JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
            public void showInfo();
          }
          // -protected 
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -protected JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
            protected char showGender();
            public void showInfo();
          }
          // -private || -p  大于或等于private权限
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -private JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            private int num;
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
            private com.chapter09.JavapTest(boolean);
            private void methodPrivate();
            int getNum(int);
            protected char showGender();
            public void showInfo();
            static {};
          }
          // -package     显示非私有的信息
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -package JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
            int getNum(int);
            protected char showGender();
            public void showInfo();
            static {};
          }
          // -sysinfo
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -sysinfo JavapTest.class
          Classfile /C:/Users/Administrator/IdeaProjects/jvm/target/classes/com/chapter09/JavapTest.class     //字节码文件路径
            Last modified 2024-5-27; size 1348 bytes             //日期
            MD5 checksum 85dc41e7e2e7128d8899b5d131d7975f       //MD5散列
            Compiled from "JavapTest.java" 
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
            int getNum(int);
            protected char showGender();
            public void showInfo();
            static {};
          }
          // -constants
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -constants JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS = 1;
            public com.chapter09.JavapTest();
            int getNum(int);
            protected char showGender();
            public void showInfo();
            static {};
          }
          // -s 输出内部类型签名
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -s JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
              descriptor: Z
            protected char gender;
              descriptor: C
            public java.lang.String info;
              descriptor: Ljava/lang/String;
            public static final int COUNTS;
              descriptor: I
            public com.chapter09.JavapTest();
              descriptor: ()V
            int getNum(int);
              descriptor: (I)I
            protected char showGender();
              descriptor: ()C
            public void showInfo();
              descriptor: ()V
            static {};
              descriptor: ()V
          }
          // -l 输出行号和本地变量表
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -l JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
              LineNumberTable:
                line 20: 0
                line 18: 4
                line 20: 10
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0      11     0  this   Lcom/chapter09/JavapTest;
            int getNum(int);
              LineNumberTable:
                line 26: 0
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0       7     0  this   Lcom/chapter09/JavapTest;
                    0       7     1     i   I
            protected char showGender();
              LineNumberTable:
                line 29: 0
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0       5     0  this   Lcom/chapter09/JavapTest;
            public void showInfo();
              LineNumberTable:
                line 32: 0
                line 33: 3
                line 34: 30
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0      31     0  this   Lcom/chapter09/JavapTest;
                    3      28     1     i   I
            static {};
              LineNumberTable:
                line 15: 0
                line 16: 3
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
          }
          // -c 对代码进行反编译
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -l JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
              LineNumberTable:
                line 20: 0
                line 18: 4
                line 20: 10
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0      11     0  this   Lcom/chapter09/JavapTest;
            int getNum(int);
              LineNumberTable:
                line 26: 0
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0       7     0  this   Lcom/chapter09/JavapTest;
                    0       7     1     i   I
            protected char showGender();
              LineNumberTable:
                line 29: 0
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0       5     0  this   Lcom/chapter09/JavapTest;
            public void showInfo();
              LineNumberTable:
                line 32: 0
                line 33: 3
                line 34: 30
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
                    0      31     0  this   Lcom/chapter09/JavapTest;
                    3      28     1     i   I
            static {};
              LineNumberTable:
                line 15: 0
                line 16: 3
              LocalVariableTable:
                Start  Length  Slot  Name   Signature
          }
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -c JavapTest.class
          Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest {
            boolean flag;
            protected char gender;
            public java.lang.String info;
            public static final int COUNTS;
            public com.chapter09.JavapTest();
              Code:
                 0: aload_0
                 1: invokespecial #1                  // Method java/lang/Object."":()V
                 4: aload_0
                 5: ldc           #2                  // String java
                 7: putfield      #3                  // Field info:Ljava/lang/String;
                10: return
            int getNum(int);
              Code:
                 0: aload_0
                 1: getfield      #5                  // Field num:I
                 4: iload_1
                 5: iadd
                 6: ireturn
            protected char showGender();
              Code:
                 0: aload_0
                 1: getfield      #6                  // Field gender:C
                 4: ireturn
            public void showInfo();
              Code:
                 0: bipush        10
                 2: istore_1
                 3: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
                 6: new           #8                  // class java/lang/StringBuilder
                 9: dup
                10: invokespecial #9                  // Method java/lang/StringBuilder."":()V
                13: aload_0
                14: getfield      #3                  // Field info:Ljava/lang/String;
                17: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                20: iload_1
                21: invokevirtual #11                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
                24: invokevirtual #12                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                27: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
                30: return
            static {};
              Code:
                 0: ldc           #14                 // String www.lotus.com
                 2: astore_0
                 3: return
          }
          // -v 显示最全的字节码反编译数据
          C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -v JavapTest.class
          Classfile /C:/Users/Administrator/IdeaProjects/jvm/target/classes/com/chapter09/JavapTest.class         //位置
            Last modified 2024-5-27; size 1348 bytes             //日期,大小
            MD5 checksum 85dc41e7e2e7128d8899b5d131d7975f        //MD5散列值
            Compiled from "JavapTest.java"
          public class com.chapter09.JavapTest
            minor version: 0                     //副版本号
            major version: 52                   //主版本号
            flags: ACC_PUBLIC, ACC_SUPER           //访问标识
          Constant pool:
             #1 = Methodref          #16.#46        // java/lang/Object."":()V
             #2 = String             #47            // java
             #3 = Fieldref           #15.#48        // com/chapter09/JavapTest.info:Ljava/lang/String;
             #4 = Fieldref           #15.#49        // com/chapter09/JavapTest.flag:Z
             #5 = Fieldref           #15.#50        // com/chapter09/JavapTest.num:I
             #6 = Fieldref           #15.#51        // com/chapter09/JavapTest.gender:C
             #7 = Fieldref           #52.#53        // java/lang/System.out:Ljava/io/PrintStream;
             #8 = Class              #54            // java/lang/StringBuilder
             #9 = Methodref          #8.#46         // java/lang/StringBuilder."":()V
            #10 = Methodref          #8.#55         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            #11 = Methodref          #8.#56         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
            #12 = Methodref          #8.#57         // java/lang/StringBuilder.toString:()Ljava/lang/String;
            #13 = Methodref          #58.#59        // java/io/PrintStream.println:(Ljava/lang/String;)V
            #14 = String             #60            // www.lotus.com
            #15 = Class              #61            // com/chapter09/JavapTest
            #16 = Class              #62            // java/lang/Object
            #17 = Utf8               num
            #18 = Utf8               I
            #19 = Utf8               flag
            #20 = Utf8               Z
            #21 = Utf8               gender
            #22 = Utf8               C
            #23 = Utf8               info
            #24 = Utf8               Ljava/lang/String;
            #25 = Utf8               COUNTS
            #26 = Utf8               ConstantValue
            #27 = Integer            1
            #28 = Utf8               
            #29 = Utf8               ()V
            #30 = Utf8               Code
            #31 = Utf8               LineNumberTable
            #32 = Utf8               LocalVariableTable
            #33 = Utf8               this
            #34 = Utf8               Lcom/chapter09/JavapTest;
            #35 = Utf8               (Z)V
            #36 = Utf8               methodPrivate
            #37 = Utf8               getNum
            #38 = Utf8               (I)I
            #39 = Utf8               i
            #40 = Utf8               showGender
            #41 = Utf8               ()C
            #42 = Utf8               showInfo
            #43 = Utf8               
            #44 = Utf8               SourceFile
            #45 = Utf8               JavapTest.java
            #46 = NameAndType        #28:#29        // "":()V
            #47 = Utf8               java
            #48 = NameAndType        #23:#24        // info:Ljava/lang/String;
            #49 = NameAndType        #19:#20        // flag:Z
            #50 = NameAndType        #17:#18        // num:I
            #51 = NameAndType        #21:#22        // gender:C
            #52 = Class              #63            // java/lang/System
            #53 = NameAndType        #64:#65        // out:Ljava/io/PrintStream;
            #54 = Utf8               java/lang/StringBuilder
            #55 = NameAndType        #66:#67        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            #56 = NameAndType        #66:#68        // append:(I)Ljava/lang/StringBuilder;
            #57 = NameAndType        #69:#70        // toString:()Ljava/lang/String;
            #58 = Class              #71            // java/io/PrintStream
            #59 = NameAndType        #72:#73        // println:(Ljava/lang/String;)V
            #60 = Utf8               www.lotus.com
            #61 = Utf8               com/chapter09/JavapTest
            #62 = Utf8               java/lang/Object
            #63 = Utf8               java/lang/System
            #64 = Utf8               out
            #65 = Utf8               Ljava/io/PrintStream;
            #66 = Utf8               append
            #67 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
            #68 = Utf8               (I)Ljava/lang/StringBuilder;
            #69 = Utf8               toString
            #70 = Utf8               ()Ljava/lang/String;
            #71 = Utf8               java/io/PrintStream
            #72 = Utf8               println
            #73 = Utf8               (Ljava/lang/String;)V
          { //-----------------------------------------------方法
          //字段表集合信息
            boolean flag;          //字段名
              descriptor: Z        //字段描述符(字段类型)
              flags:               //字段访问标识
            protected char gender;
              descriptor: C
              flags: ACC_PROTECTED
            public java.lang.String info;
              descriptor: Ljava/lang/String;
              flags: ACC_PUBLIC
            public static final int COUNTS;
              descriptor: I
              flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
              ConstantValue: int 1                             //常量字段的属性:ConstantValue,保存常量的值
          //-----------------------------------------------方法
            public com.chapter09.JavapTest();
              descriptor: ()V
              flags: ACC_PUBLIC
              Code:
                stack=2, locals=1, args_size=1
                   0: aload_0
                   1: invokespecial #1                  // Method java/lang/Object."":()V
                   4: aload_0
                   5: ldc           #2                  // String java
                   7: putfield      #3                  // Field info:Ljava/lang/String;
                  10: return
                LineNumberTable:
                  line 20: 0
                  line 18: 4
                  line 20: 10
                LocalVariableTable:
                  Start  Length  Slot  Name   Signature
                      0      11     0  this   Lcom/chapter09/JavapTest;
            int getNum(int);
              descriptor: (I)I
              flags:
              Code:
                stack=2, locals=2, args_size=2
                   0: aload_0
                   1: getfield      #5                  // Field num:I
                   4: iload_1
                   5: iadd
                   6: ireturn
                LineNumberTable:
                  line 26: 0
                LocalVariableTable:
                  Start  Length  Slot  Name   Signature
                      0       7     0  this   Lcom/chapter09/JavapTest;
                      0       7     1     i   I
            protected char showGender();
              descriptor: ()C
              flags: ACC_PROTECTED
              Code:
                stack=1, locals=1, args_size=1
                   0: aload_0
                   1: getfield      #6                  // Field gender:C
                   4: ireturn
                LineNumberTable:
                  line 29: 0
                LocalVariableTable:
                  Start  Length  Slot  Name   Signature
                      0       5     0  this   Lcom/chapter09/JavapTest;
            public void showInfo();
              descriptor: ()V                                   //方法描述符:方法的形参列表、返回值类型
              flags: ACC_PUBLIC                                 //方法的访问标识
              Code:                                             //方法Code属性
                stack=3, locals=2, args_size=1                  //stack:操作数栈的最大深度,locals:局部变量表的长度,args_size:方法接收参数的个数
             //偏移量  操作码        操作数
                   0: bipush        10
                   2: istore_1
                   3: getstatic     #7 //#7常量表索引                  // Field java/lang/System.out:Ljava/io/PrintStream;
                   6: new           #8                  // class java/lang/StringBuilder
                   9: dup
                  10: invokespecial #9                  // Method java/lang/StringBuilder."":()V
                  13: aload_0
                  14: getfield      #3                  // Field info:Ljava/lang/String;
                  17: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                  20: iload_1
                  21: invokevirtual #11                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
                  24: invokevirtual #12                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                  27: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
                  30: return
                LineNumberTable:             //行号表,当前字节码指令偏移量与Java源程序中代码的行号一一对应关系
                  line 32: 0
                  line 33: 3
                  line 34: 30
                LocalVariableTable:          //局部变量表,描述内部局部变量的相关信息
                  Start  Length  Slot  Name   Signature
                      0      31     0  this   Lcom/chapter09/JavapTest;
                      3      28     1     i   I
            static {};
              descriptor: ()V
              flags: ACC_STATIC
              Code:
                stack=1, locals=1, args_size=0
                   0: ldc           #14                 // String www.lotus.com
                   2: astore_0
                   3: return
                LineNumberTable:
                  line 15: 0
                  line 16: 3
                LocalVariableTable:
                  Start  Length  Slot  Name   Signature
          }
          SourceFile: "JavapTest.java"                         //附加属性:当前字节码对应的源文件的文件名
          

转载请注明来自码农世界,本文标题:《JVM学习-javap解析Class文件》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,70人围观)参与讨论

还没有评论,来说两句吧...

Top