文章目录
解析Class文件解析前言编译java文件讲解
魔数版本号常量池
常量池大小常量池内容
字面量符号引用 总结
前言
在正式进入JVM结构学习之前我们先了解一下.class文件的结构。
编译java文件
我们为了尽可能的多出现Java语法的相关概念,我们写了如下的代码:
package com.pai;
import java.util.linkedList;
import java.util.List;
public class Student implements Person{
private static String name;
private static final Integer SEX = 1;
public List teacherList;
Student() {
teacherList = new linkedList<>();
}
@Override
public void eat(String food) {
System.out.println(food);
}
public void eat(String food, String water) {
System.out.println(water);
eat(food);
}
public void addTeacher(Teacher teacher) {
teacherList.add(teacher);
}
public static void main(String[] args) {
Student student = new Student();
student.eat("rice", "juice");
}
}
将源文件编译后生成.class文件,使用二进制文本阅读器解读如下:
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: CA FE BA BE 00 00 00 34 00 50 0A 00 10 00 32 07 J~:>...4.P....2. 00000010: 00 33 0A 00 02 00 32 09 00 09 00 34 09 00 35 00 .3....2....4..5. 00000020: 36 0A 00 37 00 38 0A 00 09 00 39 0B 00 3A 00 3B 6..7.8....9..:.; 00000030: 07 00 3C 0A 00 09 00 32 08 00 3D 08 00 3E 0A 00 ..<....2..=..>.. 00000040: 09 00 3F 0A 00 40 00 41 09 00 09 00 42 07 00 43 ..?..@.A....B..C 00000050: 07 00 44 01 00 04 6E 61 6D 65 01 00 12 4C 6A 61 ..D...name...Lja 00000060: 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 va/lang/String;. 00000070: 00 03 53 45 58 01 00 13 4C 6A 61 76 61 2F 6C 61 ..SEX...Ljava/la 00000080: 6E 67 2F 49 6E 74 65 67 65 72 3B 01 00 0B 74 65 ng/Integer;...te 00000090: 61 63 68 65 72 4C 69 73 74 01 00 10 4C 6A 61 76 acherList...Ljav 000000a0: 61 2F 75 74 69 6C 2F 4C 69 73 74 3B 01 00 09 53 a/util/List;...S 000000b0: 69 67 6E 61 74 75 72 65 01 00 23 4C 6A 61 76 61 ignature..#Ljava 000000c0: 2F 75 74 69 6C 2F 4C 69 73 74 3C 4C 63 6F 6D 2F /util/List讲解 魔数 版本号;.. 000000e0: 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 . ...()V... 000000f0: 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 Code...LineNumbe 00000100: 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 rTable...LocalVa 00000110: 72 69 61 62 6C 65 54 61 62 6C 65 01 00 04 74 68 riableTable...th 00000120: 69 73 01 00 11 4C 63 6F 6D 2F 70 61 69 2F 53 74 is...Lcom/pai/St 00000130: 75 64 65 6E 74 3B 01 00 03 65 61 74 01 00 15 28 udent;...eat...( 00000140: 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E Ljava/lang/Strin 00000150: 67 3B 29 56 01 00 04 66 6F 6F 64 01 00 27 28 4C g;)V...food..'(L 00000160: 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 java/lang/String 00000170: 3B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 ;Ljava/lang/Stri 00000180: 6E 67 3B 29 56 01 00 05 77 61 74 65 72 01 00 0A ng;)V...water... 00000190: 61 64 64 54 65 61 63 68 65 72 01 00 14 28 4C 63 addTeacher...(Lc 000001a0: 6F 6D 2F 70 61 69 2F 54 65 61 63 68 65 72 3B 29 om/pai/Teacher;) 000001b0: 56 01 00 07 74 65 61 63 68 65 72 01 00 11 4C 63 V...teacher...Lc 000001c0: 6F 6D 2F 70 61 69 2F 54 65 61 63 68 65 72 3B 01 om/pai/Teacher;. 000001d0: 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 ..main...([Ljava 000001e0: 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 /lang/String;)V. 000001f0: 00 04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F ..args...[Ljava/ 00000200: 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 07 73 lang/String;...s 00000210: 74 75 64 65 6E 74 01 00 08 3C 63 6C 69 6E 69 74 tudent... ...SourceFile.. 00000230: 0C 53 74 75 64 65 6E 74 2E 6A 61 76 61 0C 00 1A .Student.java... 00000240: 00 1B 01 00 14 6A 61 76 61 2F 75 74 69 6C 2F 4C .....java/util/L 00000250: 69 6E 6B 65 64 4C 69 73 74 0C 00 16 00 17 07 00 inkedList....... 00000260: 45 0C 00 46 00 47 07 00 48 0C 00 49 00 22 0C 00 E..F.G..H..I.".. 00000270: 21 00 22 07 00 4A 0C 00 4B 00 4C 01 00 0F 63 6F !."..J..K.L...co 00000280: 6D 2F 70 61 69 2F 53 74 75 64 65 6E 74 01 00 04 m/pai/Student... 00000290: 72 69 63 65 01 00 05 6A 75 69 63 65 0C 00 21 00 rice...juice..!. 000002a0: 24 07 00 4D 0C 00 4E 00 4F 0C 00 14 00 15 01 00 $..M..N.O....... 000002b0: 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 .java/lang/Objec 000002c0: 74 01 00 0E 63 6F 6D 2F 70 61 69 2F 50 65 72 73 t...com/pai/Pers 000002d0: 6F 6E 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 on...java/lang/S 000002e0: 79 73 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A ystem...out...Lj 000002f0: 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 ava/io/PrintStre 00000300: 61 6D 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 am;...java/io/Pr 00000310: 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E intStream...prin 00000320: 74 6C 6E 01 00 0E 6A 61 76 61 2F 75 74 69 6C 2F tln...java/util/ 00000330: 4C 69 73 74 01 00 03 61 64 64 01 00 15 28 4C 6A List...add...(Lj 00000340: 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 3B ava/lang/Object; 00000350: 29 5A 01 00 11 6A 61 76 61 2F 6C 61 6E 67 2F 49 )Z...java/lang/I 00000360: 6E 74 65 67 65 72 01 00 07 76 61 6C 75 65 4F 66 nteger...valueOf 00000370: 01 00 16 28 49 29 4C 6A 61 76 61 2F 6C 61 6E 67 ...(I)Ljava/lang 00000380: 2F 49 6E 74 65 67 65 72 3B 00 21 00 09 00 10 00 /Integer;.!..... 00000390: 01 00 11 00 03 00 0A 00 12 00 13 00 00 00 1A 00 ................ 000003a0: 14 00 15 00 00 00 01 00 16 00 17 00 01 00 18 00 ................ 000003b0: 00 00 02 00 19 00 06 00 00 00 1A 00 1B 00 01 00 ................ 000003c0: 1C 00 00 00 42 00 03 00 01 00 00 00 10 2A B7 00 ....B........*7. 000003d0: 01 2A BB 00 02 59 B7 00 03 B5 00 04 B1 00 00 00 .*;..Y7..5..1... 000003e0: 02 00 1D 00 00 00 0E 00 03 00 00 00 11 00 04 00 ................ 000003f0: 12 00 0F 00 13 00 1E 00 00 00 0C 00 01 00 00 00 ................ 00000400: 10 00 1F 00 20 00 00 00 01 00 21 00 22 00 01 00 ..........!."... 00000410: 1C 00 00 00 40 00 02 00 02 00 00 00 08 B2 00 05 ....@........2.. 00000420: 2B B6 00 06 B1 00 00 00 02 00 1D 00 00 00 0A 00 +6..1........... 00000430: 02 00 00 00 17 00 07 00 18 00 1E 00 00 00 16 00 ................ 00000440: 02 00 00 00 08 00 1F 00 20 00 00 00 00 00 08 00 ................ 00000450: 23 00 13 00 01 00 01 00 21 00 24 00 01 00 1C 00 #.......!.$..... 00000460: 00 00 53 00 02 00 03 00 00 00 0D B2 00 05 2C B6 ..S........2..,6 00000470: 00 06 2A 2B B6 00 07 B1 00 00 00 02 00 1D 00 00 ..*+6..1........ 00000480: 00 0E 00 03 00 00 00 1B 00 07 00 1C 00 0C 00 1D ................ 00000490: 00 1E 00 00 00 20 00 03 00 00 00 0D 00 1F 00 20 ................ 000004a0: 00 00 00 00 00 0D 00 23 00 13 00 01 00 00 00 0D .......#........ 000004b0: 00 25 00 13 00 02 00 01 00 26 00 27 00 01 00 1C .%.......&.'.... 000004c0: 00 00 00 44 00 02 00 02 00 00 00 0C 2A B4 00 04 ...D........*4.. 000004d0: 2B B9 00 08 02 00 57 B1 00 00 00 02 00 1D 00 00 +9....W1........ 000004e0: 00 0A 00 02 00 00 00 20 00 0B 00 21 00 1E 00 00 ...........!.... 000004f0: 00 16 00 02 00 00 00 0C 00 1F 00 20 00 00 00 00 ................ 00000500: 00 0C 00 28 00 29 00 01 00 09 00 2A 00 2B 00 01 ...(.).....*.+.. 00000510: 00 1C 00 00 00 4D 00 03 00 02 00 00 00 11 BB 00 .....M........;. 00000520: 09 59 B7 00 0A 4C 2B 12 0B 12 0C B6 00 0D B1 00 .Y7..L+....6..1. 00000530: 00 00 02 00 1D 00 00 00 0E 00 03 00 00 00 24 00 ..............$. 00000540: 08 00 25 00 10 00 26 00 1E 00 00 00 16 00 02 00 ..%...&......... 00000550: 00 00 11 00 2C 00 2D 00 00 00 08 00 09 00 2E 00 ....,.-......... 00000560: 20 00 01 00 08 00 2F 00 1B 00 01 00 1C 00 00 00 ....../......... 00000570: 20 00 01 00 00 00 00 00 08 04 B8 00 0E B3 00 0F ..........8..3.. 00000580: B1 00 00 00 01 00 1D 00 00 00 06 00 01 00 00 00 1............... 00000590: 0E 00 01 00 30 00 00 00 02 00 31 ....0.....1
这里 0x0000是次版本号,0x0034是主版本号。主版本号的十六进制换算成十进制为52,也就是我们非常熟悉的Java8代码。这说明该代码只能被8及其以后的高版本的JVM运行。
转换为十进制为80,也就是该段程序中有79个常量。
我们使用javap -v Student.class命令反编译,查看该程序中的常量池。
Classfile /F:/GITHUB/jvm/target/classes/com/pai/Student.class Last modified 2022-3-28; size 1435 bytes MD5 checksum b80b0af23b324be4b81d7765a4b36f45 Compiled from "Student.java" public class com.pai.Student implements com.pai.Person minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #16.#50 // java/lang/Object."":()V #2 = Class #51 // java/util/linkedList #3 = Methodref #2.#50 // java/util/linkedList." ":()V #4 = Fieldref #9.#52 // com/pai/Student.teacherList:Ljava/util/List; #5 = Fieldref #53.#54 // java/lang/System.out:Ljava/io/PrintStream; #6 = Methodref #55.#56 // java/io/PrintStream.println:(Ljava/lang/String;)V #7 = Methodref #9.#57 // com/pai/Student.eat:(Ljava/lang/String;)V #8 = InterfaceMethodref #58.#59 // java/util/List.add:(Ljava/lang/Object;)Z #9 = Class #60 // com/pai/Student #10 = Methodref #9.#50 // com/pai/Student." ":()V #11 = String #61 // rice #12 = String #62 // juice #13 = Methodref #9.#63 // com/pai/Student.eat:(Ljava/lang/String;Ljava/lang/String;)V #14 = Methodref #64.#65 // java/lang/Integer.valueOf:(I)Ljava/lang/Integer; #15 = Fieldref #9.#66 // com/pai/Student.SEX:Ljava/lang/Integer; #16 = Class #67 // java/lang/Object #17 = Class #68 // com/pai/Person #18 = Utf8 name #19 = Utf8 Ljava/lang/String; #20 = Utf8 SEX #21 = Utf8 Ljava/lang/Integer; #22 = Utf8 teacherList #23 = Utf8 Ljava/util/List; #24 = Utf8 Signature #25 = Utf8 Ljava/util/List ; #26 = Utf8 #27 = Utf8 ()V #28 = Utf8 Code #29 = Utf8 LineNumberTable #30 = Utf8 LocalVariableTable #31 = Utf8 this #32 = Utf8 Lcom/pai/Student; #33 = Utf8 eat #34 = Utf8 (Ljava/lang/String;)V #35 = Utf8 food #36 = Utf8 (Ljava/lang/String;Ljava/lang/String;)V #37 = Utf8 water #38 = Utf8 addTeacher #39 = Utf8 (Lcom/pai/Teacher;)V #40 = Utf8 teacher #41 = Utf8 Lcom/pai/Teacher; #42 = Utf8 main #43 = Utf8 ([Ljava/lang/String;)V #44 = Utf8 args #45 = Utf8 [Ljava/lang/String; #46 = Utf8 student #47 = Utf8 #48 = Utf8 SourceFile #49 = Utf8 Student.java #50 = NameAndType #26:#27 // " ":()V #51 = Utf8 java/util/linkedList #52 = NameAndType #22:#23 // teacherList:Ljava/util/List; #53 = Class #69 // java/lang/System #54 = NameAndType #70:#71 // out:Ljava/io/PrintStream; #55 = Class #72 // java/io/PrintStream #56 = NameAndType #73:#34 // println:(Ljava/lang/String;)V #57 = NameAndType #33:#34 // eat:(Ljava/lang/String;)V #58 = Class #74 // java/util/List #59 = NameAndType #75:#76 // add:(Ljava/lang/Object;)Z #60 = Utf8 com/pai/Student #61 = Utf8 rice #62 = Utf8 juice #63 = NameAndType #33:#36 // eat:(Ljava/lang/String;Ljava/lang/String;)V #64 = Class #77 // java/lang/Integer #65 = NameAndType #78:#79 // valueOf:(I)Ljava/lang/Integer; #66 = NameAndType #20:#21 // SEX:Ljava/lang/Integer; #67 = Utf8 java/lang/Object #68 = Utf8 com/pai/Person #69 = Utf8 java/lang/System #70 = Utf8 out #71 = Utf8 Ljava/io/PrintStream; #72 = Utf8 java/io/PrintStream #73 = Utf8 println #74 = Utf8 java/util/List #75 = Utf8 add #76 = Utf8 (Ljava/lang/Object;)Z #77 = Utf8 java/lang/Integer #78 = Utf8 valueOf #79 = Utf8 (I)Ljava/lang/Integer; { public java.util.List teacherList; descriptor: Ljava/util/List; flags: ACC_PUBLIC Signature: #25 // Ljava/util/List ; com.pai.Student(); descriptor: ()V flags: Code: stack=3, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object." ":()V 4: aload_0 5: new #2 // class java/util/linkedList 8: dup 9: invokespecial #3 // Method java/util/linkedList." ":()V 12: putfield #4 // Field teacherList:Ljava/util/List; 15: return LineNumberTable: line 17: 0 line 18: 4 line 19: 15 LocalVariableTable: Start Length Slot Name Signature 0 16 0 this Lcom/pai/Student; public void eat(java.lang.String); descriptor: (Ljava/lang/String;)V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=2 0: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_1 4: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 7: return LineNumberTable: line 23: 0 line 24: 7 LocalVariableTable: Start Length Slot Name Signature 0 8 0 this Lcom/pai/Student; 0 8 1 food Ljava/lang/String; public void eat(java.lang.String, java.lang.String); descriptor: (Ljava/lang/String;Ljava/lang/String;)V flags: ACC_PUBLIC Code: stack=2, locals=3, args_size=3 0: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_2 4: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 7: aload_0 8: aload_1 9: invokevirtual #7 // Method eat:(Ljava/lang/String;)V 12: return LineNumberTable: line 27: 0 line 28: 7 line 29: 12 LocalVariableTable: Start Length Slot Name Signature 0 13 0 this Lcom/pai/Student; 0 13 1 food Ljava/lang/String; 0 13 2 water Ljava/lang/String; public void addTeacher(com.pai.Teacher); descriptor: (Lcom/pai/Teacher;)V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: getfield #4 // Field teacherList:Ljava/util/List; 4: aload_1 5: invokeinterface #8, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 10: pop 11: return LineNumberTable: line 32: 0 line 33: 11 LocalVariableTable: Start Length Slot Name Signature 0 12 0 this Lcom/pai/Student; 0 12 1 teacher Lcom/pai/Teacher; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=2, args_size=1 0: new #9 // class com/pai/Student 3: dup 4: invokespecial #10 // Method " ":()V 7: astore_1 8: aload_1 9: ldc #11 // String rice 11: ldc #12 // String juice 13: invokevirtual #13 // Method eat:(Ljava/lang/String;Ljava/lang/String;)V 16: return LineNumberTable: line 36: 0 line 37: 8 line 38: 16 LocalVariableTable: Start Length Slot Name Signature 0 17 0 args [Ljava/lang/String; 8 9 1 student Lcom/pai/Student; static {}; descriptor: ()V flags: ACC_STATIC Code: stack=1, locals=0, args_size=0 0: iconst_1 1: invokestatic #14 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 4: putstatic #15 // Field SEX:Ljava/lang/Integer; 7: return LineNumberTable: line 14: 0 } SourceFile: "Student.java"
我们看到常量池的数量为79.
常量池内容常量池中主要存放两大类常量:字面量和符号引用.
- 字面量
文本字符串被final修饰的常量值
- 符号引用
类和接口的全限定名字段的名称和描述符方法的名称和描述符
下面我们举例说明:1. 常量池定义的顺序 2. 字面量和符号引用的举例 3. 如何阅读常量池。
字面量 符号引用总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。



