JVM学习-javap解析Class文件

解析字节码的作用
  • 通过反编译生成字节码文件,可以深入了解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有如下选项
java 复制代码
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."<init>":()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."<init>":()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."<init>":()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."<init>":()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               <init>
  #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               <clinit>
  #44 = Utf8               SourceFile
  #45 = Utf8               JavapTest.java
  #46 = NameAndType        #28:#29        // "<init>":()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."<init>":()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."<init>":()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"                         //附加属性:当前字节码对应的源文件的文件名
相关推荐
_BugMan24 分钟前
【IDEA】干活?一个IDEA即可,集成开发平台打造攻略
java·ide·intellij-idea
YA3331 小时前
java设计模式二、工厂
java·开发语言·设计模式
金色天际线-1 小时前
Nginx 优化与防盗链配置指南
java·后端·spring
我爱挣钱我也要早睡!2 小时前
Java 复习笔记
java·开发语言·笔记
AD钙奶-lalala4 小时前
Mac OS上搭建 http server
java
知识分享小能手5 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
茯苓gao8 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾8 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
皮皮林5518 小时前
SpringBoot 全局/局部双模式 Gzip 压缩实战:14MB GeoJSON 秒变 3MB
java·spring boot
weixin_456904278 小时前
Spring Boot 用户管理系统
java·spring boot·后端