重学JVM之class文件结构

先准备一个简单的java文件

public class Person {
    private String name = "jack";
    private int age;
    private final double salary = 100;
    private static String address;
    private final static String hobby = "programming";
    private static Object obj = new Object();
    public void say(){
        System.out.println("person say ...");
    }
    public static int calc(int op1,int op2){
        op1 =3;
        int result = op1 + op2;
        Object object = new Object();
        return result;
    }
    public static void main(String[] args) {
        calc(1,2);
    }
}

经过javac命令编译后得到一个class文件,用UE编辑器打开后得到的class文件格式是如下这样的
重学JVM之class文件结构_第1张图片
从https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html 的官网可以看到,class文件的结构是由以下的格式进行排列的,u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节,以“_info”结尾的则称为表。class文件的顺序,长度都是都是固定,不可以随便变动
重学JVM之class文件结构_第2张图片
对应中文版本如下
重学JVM之class文件结构_第3张图片
class文件的第一个首先是魔数,魔数占4个字节,也就是CA FE BA BE,作用是确定文件是否为一个能被虚拟机识别的class文件 ,魔数之后就是次版本号(即00 00);主版本号(00 34);
各个版本的对应关系,本例中00 34也就是对应的是jdk1.8,也就是说是由jdk1.8编译的。
重学JVM之class文件结构_第4张图片
常量池数量(00 3A),转换为十进制就是58,也就是说有58个常量,
constant_pool=constant_pool_count-1,本例中也就是常量有57个,我们可以通过javap -v Person.class命令得到如下反编译之后的结果,可以看到Constant pool是从1到57的

Classfile /E:/project/study/src/main/java/com/sample/study/test/Person.class
  Last modified 2020-5-21; size 911 bytes
  MD5 checksum 934fb0bd52076255f9a7e34b641c3476
  Compiled from "Person.java"
public class com.sample.study.test.Person
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #10.#38        // java/lang/Object."":()V
   #2 = String             #39            // jack
   #3 = Fieldref           #13.#40        // com/sample/study/test/Person.name:Ljava/lang/String;
   #4 = Double             100.0d
   #6 = Fieldref           #13.#41        // com/sample/study/test/Person.salary:D
   #7 = Fieldref           #42.#43        // java/lang/System.out:Ljava/io/PrintStream;
   #8 = String             #44            // person say ...
   #9 = Methodref          #45.#46        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #10 = Class              #47            // java/lang/Object
  #11 = Methodref          #13.#48        // com/sample/study/test/Person.calc:(II)I
  #12 = Fieldref           #13.#49        // com/sample/study/test/Person.obj:Ljava/lang/Object;
  #13 = Class              #50            // com/sample/study/test/Person
  #14 = Utf8               name
  #15 = Utf8               Ljava/lang/String;
  #16 = Utf8               age
  #17 = Utf8               I
  #18 = Utf8               salary
  #19 = Utf8               D
  #20 = Utf8               ConstantValue
  #21 = Utf8               address
  #22 = Utf8               hobby
  #23 = String             #51            // programming
  #24 = Utf8               obj
  #25 = Utf8               Ljava/lang/Object;
  #26 = Utf8               
  #27 = Utf8               ()V
  #28 = Utf8               Code
  #29 = Utf8               LineNumberTable
  #30 = Utf8               say
  #31 = Utf8               calc
  #32 = Utf8               (II)I
  #33 = Utf8               main
  #34 = Utf8               ([Ljava/lang/String;)V
  #35 = Utf8               
  #36 = Utf8               SourceFile
  #37 = Utf8               Person.java
  #38 = NameAndType        #26:#27        // "":()V
  #39 = Utf8               jack
  #40 = NameAndType        #14:#15        // name:Ljava/lang/String;
  #41 = NameAndType        #18:#19        // salary:D
  #42 = Class              #52            // java/lang/System
  #43 = NameAndType        #53:#54        // out:Ljava/io/PrintStream;
  #44 = Utf8               person say ...
  #45 = Class              #55            // java/io/PrintStream
  #46 = NameAndType        #56:#57        // println:(Ljava/lang/String;)V
  #47 = Utf8               java/lang/Object
  #48 = NameAndType        #31:#32        // calc:(II)I
  #49 = NameAndType        #24:#25        // obj:Ljava/lang/Object;
  #50 = Utf8               com/sample/study/test/Person
  #51 = Utf8               programming
  #52 = Utf8               java/lang/System
  #53 = Utf8               out
  #54 = Utf8               Ljava/io/PrintStream;
  #55 = Utf8               java/io/PrintStream
  #56 = Utf8               println
  #57 = Utf8               (Ljava/lang/String;)V
{
  public com.sample.study.test.Person();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: aload_0
         5: ldc           #2                  // String jack
         7: putfield      #3                  // Field name:Ljava/lang/String;
        10: aload_0
        11: ldc2_w        #4                  // double 100.0d
        14: putfield      #6                  // Field salary:D
        17: return
      LineNumberTable:
        line 3: 0
        line 4: 4
        line 6: 10

  public void say();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #8                  // String person say ...
         5: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 11: 0
        line 12: 8

  public static int calc(int, int);
    descriptor: (II)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=4, args_size=2
         0: iconst_3
         1: istore_0
         2: iload_0
         3: iload_1
         4: iadd
         5: istore_2
         6: new           #10                 // class java/lang/Object
         9: dup
        10: invokespecial #1                  // Method java/lang/Object."":()V
        13: astore_3
        14: iload_2
        15: ireturn
      LineNumberTable:
        line 14: 0
        line 15: 2
        line 16: 6
        line 17: 14

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: iconst_1
         1: iconst_2
         2: invokestatic  #11                 // Method calc:(II)I
         5: pop
         6: return
      LineNumberTable:
        line 20: 0
        line 21: 6

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: new           #10                 // class java/lang/Object
         3: dup
         4: invokespecial #1                  // Method java/lang/Object."":()V
         7: putstatic     #12                 // Field obj:Ljava/lang/Object;
        10: return
      LineNumberTable:
        line 9: 0
}
SourceFile: "Person.java"

access_flags:访问标志,主要标记的是接口或者类的信息,接口类型等
重学JVM之class文件结构_第5张图片

你可能感兴趣的:(JAVA基础)