如何方便的查看class结构?
Class文件的整体结构是怎样的?
JVM规范要求每一个字节码文件都要由十部分按照固定的顺序组成。

class文件各数据项之间没有分隔符。
class文件采用类似于C语言的伪结构存储数据,这种伪结构只有两种数据类型:无符号数和表。

参考:
- 《深入理解Java虚拟机(第2版)》第6章 类文件结构
方法表的具体存储格式是怎样的?
方法表也是由两部分组成:
- 第一部分为两个字节描述方法的个数。
- 第二部分为每个方法的详细信息。方法的详细信息较为复杂,包括方法的访问标志、方法名、方法的描述符以及方法的属性。

方法名索引、描述符索引,这两个的索引指的是在常量池中的索引,方法名和描述符都存储在class的常量池中,可以通过索引值在常量池中找到。
属性包括以下3个部分:
- “Code区”:源代码对应的JVM指令操作码,在进行字节码增强时重点操作的就是“Code区”这一部分。
- “LineNumberTable”:行号表,将Code区的操作码和源代码中的行号对应,Debug时会起到作用(源代码走一行,需要走多少个JVM指令操作码)。
- “LocalVariableTable”:本地变量表,包含This和局部变量,之所以可以在每一个方法内部都可以调用This,是因为JVM将This作为每一个方法的第一个参数隐式进行传入。当然,这是针对非Static方法而言。
参考:
class文件结构一个具体的案例?
参考《深入理解Java虚拟机(第2版)》第6章 类文件结构 6.3.7 属性表集合 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| Classfile ~/Demo.class Last modified 2020-9-30; size 338 bytes MD5 checksum d2cf9d824e949e4dcc98ac47657cba67 Compiled from "Demo.java" public class Demo minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#18 #2 = Fieldref #3.#19 #3 = Class #20 #4 = Class #21 #5 = Utf8 m #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 LDemo; #14 = Utf8 inc #15 = Utf8 ()I #16 = Utf8 SourceFile #17 = Utf8 Demo.java #18 = NameAndType #7:#8 #19 = NameAndType #5:#6 #20 = Utf8 Demo #21 = Utf8 java/lang/Object { public Demo(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LDemo;
public int inc(); descriptor: ()I flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: getfield #2 4: iconst_1 5: iadd 6: ireturn LineNumberTable: line 5: 0 LocalVariableTable: Start Length Slot Name Signature 0 7 0 this LDemo; } SourceFile: "Demo.java"
|
参考资料