简单梳理Java Class文件结构(基于JDK1.8)

本文深入剖析Java Class文件结构,涵盖魔数、版本号、常量池、访问标志等核心概念,通过实例解读字节码,揭示Class文件的奥秘。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

高效学习博客:
Class类文件结构: https://www.cnblogs.com/wade-luffy/p/5929325.html
Java Class文件结构解析 及 实例分析验证 : https://blog.youkuaiyun.com/tjiyu/article/details/53870153
Class文件中的常量池详解(上): https://blog.youkuaiyun.com/wangtaomtk/article/details/52267548
官方java class文件结构文档:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
可以下载个010Editor,打开class文件后会提示下载解析class文件脚本,之后就很方便,每一项都清清楚楚是干嘛的。
http://www.sweetscape.com/download/010editor/

一.Class文件整体结构:

全在这张图中了,再结合后面解析二进制文件字节码的例子,基本就掌握了大概的结构规则,当然这只是简单的解析。
在这里插入图片描述
本图的draw.io源文件在百度盘中下载,可再自行添加修改:
链接: https://pan.baidu.com/s/1FMPUeBGaCKFZXEh-M8a6vA 提取码: nhwf

Class文件中只有两类数据类型:

  1. 无符号数:
    无符号数属于基本的数据类型,以u1、u2、u4、u8来表示一个字节、两个字节…的无符号数;
    无符号数用来描述数字、索引引用、数量值或UTF-8编码构成的字符串值。
  2. 表:
    表是由多个无符号数或其他表作为数据项构成的复合数据类型,一般以"_info"结尾
    表中的项长度不固定

主要结构类型:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

讲解:

类型名称数量说明
u4magic1魔数:确定一个文件是否是Class文件
u2minor_version1Class文件的次版本号
u2major_version1Class文件的主版本号:一个JVM实例只能支持特定范围内版本号的Class文件(可以向下兼容)。
u2constant_pool_count1常量表数量
cp_infoconstant_poolconstant_pool_count-1常量池:以理解为Class文件的资源仓库,后面的其他数据项可以引用常量池内容
u2access_flags1类的访问标志信息:用于表示这个类或者接口的访问权限及基础属性。
u2this_class1指向当前类的常量索引:用来确定这个类的全限定名。
u2super_class1指向当父类的常量索引:用来确定这个类的父类的全限定名。
u2interfaces_count1接口的数量
u2interfacesinterfaces_count指向接口的常量索引:用来描述这个类实现了哪些接口。
u2fields_count1字段表数量
field_infofieldsfields_count字段表集合:描述当前类或接口声明的所有字段。
u2methods_count1方法表数量
method_infomethodsmethods_count方法表集合:只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。
u2attributes_count1属性表数量
attributes_infoattributesattributes_count属性表集合:用于描述某些场景专有的信息,如字节码的指令信息等等。

二.举个例子

1. 如下class文件:**

/home/chengang/IdeaProjects/JavaTest/src/Computer.java
public class Computer {
    final String TAG = "Log";
    private String mName;
    int mPrice;

    public Computer(String mModel, int mPrice) {
        this.mName = mModel;
        this.mPrice = mPrice;
        System.out.println(TAG + " new Computer()");
    }

    public String getName() {
        return mName;
    }

    public int getPrice() {
        return mPrice;
    }
}

2.生成如下字节码:**

用vim打开文件并二进制查看:
vim /home/chengang/IdeaProjects/JavaTest/out/production/JavaTest/Computer.class
:%!xxd
在这里插入图片描述
具体可参考:

00000000: cafe babe (魔数u4) 0000 0034(版本号u2+u2) 0032(cp_count,常量池50个,包含一个索引0的) 0a(tag:0a=10 是Methodref)00 0a(class_index:0a=10,常量池中第10项)00 1f(name_and_type_index:001f=31,常量池中第31项)08(tag:08=8 是String)  .......4.2......
00000010: 0020(string_index:0020=32,常量池第32项“Log”) 09(tag:09=9 是Fieldref)00 07(class_index:07=7,常量池中第7项,“Computer”)00 21(name_type_index:0021=33,常量池中第33项,“TAG:Ljava/lang/String;”,之后类似)09 0007 0022 0900 0700  . ....!...."....
00000020: 2309 0024 0025 0700 2608 0027 0a00 2800  #..$.%..&..'..(.
00000030: 2907 002a 0100 0354 4147 0100 124c 6a61  )..*...TAG...Lja
00000040: 7661 2f6c 616e 672f 5374 7269 6e67 3b01  va/lang/String;.
00000050: 000d 436f 6e73 7461 6e74 5661 6c75 6501  ..ConstantValue.
00000060: 0005 6d4e 616d 6501 0006 6d50 7269 6365  ..mName...mPrice
00000070: 0100 0149 0100 063c 696e 6974 3e01 0016  ...I...<init>...
00000080: 284c 6a61 7661 2f6c 616e 672f 5374 7269  (Ljava/lang/Stri
00000090: 6e67 3b49 2956 0100 0443 6f64 6501 000f  ng;I)V...Code...
000000a0: 4c69 6e65 4e75 6d62 6572 5461 626c 6501  LineNumberTable.
000000b0: 0012 4c6f 6361 6c56 6172 6961 626c 6554  ..LocalVariableT
000000c0: 6162 6c65 0100 0474 6869 7301 000a 4c43  able...this...LC
000000d0: 6f6d 7075 7465 723b 0100 066d 4d6f 6465  omputer;...mMode
000000e0: 6c01 0007 6765 744e 616d 6501 0014 2829  l...getName...()
000000f0: 4c6a 6176 612f 6c61 6e67 2f53 7472 696e  Ljava/lang/Strin
00000100: 673b 0100 0867 6574 5072 6963 6501 0003  g;...getPrice...
00000110: 2829 4901 000a 536f 7572 6365 4669 6c65  ()I...SourceFile
00000120: 0100 0d43 6f6d 7075 7465 722e 6a61 7661  ...Computer.java
00000130: 0c00 1100 2b01 0003 4c6f 670c 000b 000c  ....+...Log.....
00000140: 0c00 0e00 0c0c 000f 0010 0700 2c0c 002d  ............,..-
00000150: 002e 0100 0843 6f6d 7075 7465 7201 0012  .....Computer...
00000160: 4c6f 6720 6e65 7720 436f 6d70 7574 6572  Log new Computer
00000170: 2829 0700 2f0c 0030 0031 0100 106a 6176  ()../..0.1...jav
00000180: 612f 6c61 6e67 2f4f 626a 6563 7401 0003  a/lang/Object...
00000190: 2829 5601 0010 6a61 7661 2f6c 616e 672f  ()V...java/lang/
000001a0: 5379 7374 656d 0100 036f 7574 0100 154c  System...out...L
000001b0: 6a61 7661 2f69 6f2f 5072 696e 7453 7472  java/io/PrintStr
000001c0: 6561 6d3b 0100 136a 6176 612f 696f 2f50  eam;...java/io/P
000001d0: 7269 6e74 5374 7265 616d 0100 0770 7269  rintStream...pri
000001e0: 6e74 6c6e 0100 1528 4c6a 6176 612f 6c61  ntln...(Ljava/la
000001f0: 6e67 2f53 7472 696e 673b 2956 (在这之前为常量池)0021(类access_flag:0021=0x0020&0x001,查表代表ACC_SUPER和ACC_PUBLIC) 0007(this_class:0007=7,常量池第7项,“Computer”)  ng/String;)V.!..
00000200: 000a(super_class:000a=10,常量池第10项,“java/lang/Object”,java中所有基类都默认有一个父类Object类) 0000(interfaces_count:0000=0,无接口,因此无后面的interface部分) 0003(fields_count:0003=3,代表有3个字段,之后有三个field_info,字段表从此开始) 0010(字段access_flag:0x0010查字段的访问标志表为ACC_FINAL类型,代表着final修饰符) 000b(name_index:000b=11,常量池第11项,“TAG”) 000c(descriptor_index:000c=12,字段描述符,常量池第12项,“Ljava/lang/String;”) 0001(attributes_count:0001=1,后面有一个属性项) 000d(attribute_name_index:000d=13,常量池第13项,“ConstantValue”)  ................
00000210: 0000 0002(u4 attribute_length:2) 0002(constantvalue_index:0002=2,常量池第2项,“Log”) 0002(第2个字段的access_flag:0002=2,0x0002查表为ACC_PRIVATE,即private修饰符) 000e(name_index:000e=14,常量池第14项,“mName”) 000c(descriptor_index:000c=12,常量池第12项,“Ljava/lang/String;”) 0000(attributes_count:0000=0,后面没有属性项) 0000(第三个字段的access_flag,没有使用需要设置为0)  ................
00000220: 000f(name_index:000f=15,常量池第15项,“mPrice”) 0010(descriptor_index:0010=16,常量池项中的第16项,“I”代表Int类型) 0000(attributes_count:0,后面无属性项,字段表至此结束) 0003(methods_count=3代表后面有三个method_info,方法表从此处开始) 0001(方法的access_flag:0001=0x0001,查询方法项的access_flag为ACC_PUBLIC) 0011(name_index:0011=17,常量池中的第17项“<init>”,代表着实例构造器,如果代码中有定义构造函数,在解析的语法分析阶段被重命名为<init>()) 0012(descriptor_index:0012=18,常量池中的第18项,“(Ljava/lang/String;I)V”,代表着void类型的方法,有String和int两个类型的参数) 0001(attribute_count:0001=1,后面有一个属性项)  ................
00000230: 0013(attribute_name_index:0013=19,常量表中的第19项,“Code”,code属性,再根据code属性的组成格式,依次解析后面的每一个字节的含义) 0000 006f 0002 0003 0000 001d 2ab7  .....o........*.
00000240: 0001 2a12 02b5 0003 2a2b b500 042a 1cb5  ..*.....*+...*..
00000250: 0005 b200 0612 08b6 0009 b100 0000 0200  ................
00000260: 1400 0000 1a00 0600 0000 0600 0400 0200  ................
00000270: 0a00 0700 0f00 0800 1400 0900 1c00 0a00  ................
00000280: 1500 0000 2000 0300 0000 1d00 1600 1700  .... ...........
00000290: 0000 0000 1d00 1800 0c00 0100 0000 1d00  ................
000002a0: 0f00 1000 0200 0100 1900 1a00 0100 1300  ................
000002b0: 0000 2f00 0100 0100 0000 052a b400 04b0  ../........*....
000002c0: 0000 0002 0014 0000 0006 0001 0000 000d  ................
000002d0: 0015 0000 000c 0001 0000 0005 0016 0017  ................
000002e0: 0000 0001 001b 001c 0001 0013 0000 002f  .............../
000002f0: 0001 0001 0000 0005 2ab4 0005 ac00 0000  ........*.......
00000300: 0200 1400 0000 0600 0100 0000 1100 1500  ................
00000310: 0000 0c00 0100 0000 0500 1600 1700 0000  ................
00000320: 0100 1d00 0000 0200 1e                   .........

可以使用010Editor打开class文件,更加清晰明了:
在这里插入图片描述

3.Javap反解析结构图**

javap反编译工具,可以根据class字节码反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息:

chengang@mi:~$ javap  -v '/home/chengang/IdeaProjects/JavaTest/out/production/JavaTest/Computer.class' 
Classfile /home/chengang/IdeaProjects/JavaTEst/out/production/JavaTest/Computer.class
  Last modified Apr 26, 2019; size 809 bytes
  MD5 checksum 561774586f9e1d34a2e35a7617d17f5c
  Compiled from "Computer.java"
public class Computer
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #10.#31        // java/lang/Object."<init>":()V
   #2 = String             #32            // Log
   #3 = Fieldref           #7.#33         // Computer.TAG:Ljava/lang/String;
   #4 = Fieldref           #7.#34         // Computer.mName:Ljava/lang/String;
   #5 = Fieldref           #7.#35         // Computer.mPrice:I
   #6 = Fieldref           #36.#37        // java/lang/System.out:Ljava/io/PrintStream;
   #7 = Class              #38            // Computer
   #8 = String             #39            // Log new Computer()
   #9 = Methodref          #40.#41        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #10 = Class              #42            // java/lang/Object
  #11 = Utf8               TAG
  #12 = Utf8               Ljava/lang/String;
  #13 = Utf8               ConstantValue
  #14 = Utf8               mName
  #15 = Utf8               mPrice
  #16 = Utf8               I
  #17 = Utf8               <init>
  #18 = Utf8               (Ljava/lang/String;I)V
  #19 = Utf8               Code
  #20 = Utf8               LineNumberTable
  #21 = Utf8               LocalVariableTable
  #22 = Utf8               this
  #23 = Utf8               LComputer;
  #24 = Utf8               mModel
  #25 = Utf8               getName
  #26 = Utf8               ()Ljava/lang/String;
  #27 = Utf8               getPrice
  #28 = Utf8               ()I
  #29 = Utf8               SourceFile
  #30 = Utf8               Computer.java
  #31 = NameAndType        #17:#43        // "<init>":()V
  #32 = Utf8               Log
  #33 = NameAndType        #11:#12        // TAG:Ljava/lang/String;
  #34 = NameAndType        #14:#12        // mName:Ljava/lang/String;
  #35 = NameAndType        #15:#16        // mPrice:I
  #36 = Class              #44            // java/lang/System
  #37 = NameAndType        #45:#46        // out:Ljava/io/PrintStream;
  #38 = Utf8               Computer
  #39 = Utf8               Log new Computer()
  #40 = Class              #47            // java/io/PrintStream
  #41 = NameAndType        #48:#49        // println:(Ljava/lang/String;)V
  #42 = Utf8               java/lang/Object
  #43 = Utf8               ()V
  #44 = Utf8               java/lang/System
  #45 = Utf8               out
  #46 = Utf8               Ljava/io/PrintStream;
  #47 = Utf8               java/io/PrintStream
  #48 = Utf8               println
  #49 = Utf8               (Ljava/lang/String;)V
{
  final java.lang.String TAG;
    descriptor: Ljava/lang/String;
    flags: ACC_FINAL
    ConstantValue: String Log

  int mPrice;
    descriptor: I
    flags:

  public Computer(java.lang.String, int);
    descriptor: (Ljava/lang/String;I)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: ldc           #2                  // String Log
         7: putfield      #3                  // Field TAG:Ljava/lang/String;
        10: aload_0
        11: aload_1
        12: putfield      #4                  // Field mName:Ljava/lang/String;
        15: aload_0
        16: iload_2
        17: putfield      #5                  // Field mPrice:I
        20: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        23: ldc           #8                  // String Log new Computer()
        25: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        28: return
      LineNumberTable:
        line 6: 0
        line 2: 4
        line 7: 10
        line 8: 15
        line 9: 20
        line 10: 28
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      29     0  this   LComputer;
            0      29     1 mModel   Ljava/lang/String;
            0      29     2 mPrice   I

  public java.lang.String getName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #4                  // Field mName:Ljava/lang/String;
         4: areturn
      LineNumberTable:
        line 13: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LComputer;

  public int getPrice();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #5                  // Field mPrice:I
         4: ireturn
      LineNumberTable:
        line 17: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LComputer;
}
SourceFile: "Computer.java"

三.Class文件结构表项详细及重点

字段描述符中基本类型:

字符类型含义
Bbyte有符号字节型数
CcharUnicode 字符,UTF-16 编码
Ddouble双精度浮点数
Ffloat单精度浮点数
Iint整型数
Jlong长整数
Sshort有符号短整数
Zboolean布尔值:true/false
L Classname;reference一个名为的实例
[reference一个一维数组
Vvoidvoid返回值(其实不属于基本类型,而是VoidDescriptor)

1.魔数

Class文件开始是4个字节定义为魔数(Magic Number);

唯一作用:确定一个文件是否是Class文件

2.Class文件版本

魔数之后的4个字节标识版本号,即minor_version为0,major_version为52(0034对应的十进制),版本为52.0(符合JDK8)
各个版本的对应关系:

JDK版本号Class版本号16进制
1.145.000 00 00 2D
1.246.000 00 00 2E
1.347.000 00 00 2F
1.448.000 00 00 30
1.549.000 00 00 31
1.650.000 00 00 32
1.751.000 00 00 33
1.852.000 00 00 34

3.常量池

常量池可以理解为Class文件的资源仓库,后面的其他数据项可以引用常量池内容;
常量池每一项都是一个表包含Class文件结构及其子结构中引用的所有字符串常量、类或接口名、字段名和其它常量;
主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References);

常量池里的没一项都有如下格式:

//常量池项的通用格式
cp_info {
    u1 tag;// 1byte 标志位,标识了info[]项的内容,即 info[]属于什么类型
	u1 info[];
}

JDK 1.8 有14中常量类型及各自组成格式:

Constant TypeValue占用字节数组成部分comments
CONSTANT_Class73u1 tag;
u2 name_index;
CONSTANT_Fieldref95u1 tag;
u2 class_index;
u2 name_and_type_index;
CONSTANT_Methodref105u1 tag;
u2 class_index;
u2 name_and_type_index;
CONSTANT_InterfaceMethodref115u1 tag;
u2 class_index;
u2 name_and_type_index;`
CONSTANT_String83u1 tag;
u2 string_index;
CONSTANT_Integer35u1 tag;
u4 bytes
CONSTANT_Float45u1 tag;
u4 bytes;`
CONSTANT_Long59u1 tag;
u4 high_bytes;
u4 low_bytes;
占用2个常量表项空间
CONSTANT_Double69u1 tag;
u4 high_bytes;
u4 low_bytes;
占用2个常量表项空间
CONSTANT_NameAndType125u1 tag;
u2 name_index;
u2 descriptor_index;
CONSTANT_Utf811+2+lengthu1 tag;
u2 length;
u1 bytes[length];
CONSTANT_MethodHandle154u1 tag;
u1 reference_kind;
u2 reference_index;
CONSTANT_MethodType163u1 tag;
u2 descriptor_index;
CONSTANT_InvokeDynamic185u1 tag;
u2 bootstrap_method_attr_index;
u2 name_and_type_index;

4.类的访问标志

用于表示这个类或者接口的访问权限及基础属性;

可以用16位掩码标志,目前只使用8种(JDK1.5增加后面三种),没使用的需要设置为0;

类的access_flags表:

标记名含义
ACC_PUBLIC0x0001可以被包的类外访问。
ACC_FINAL0x0010不允许有子类。
ACC_SUPER0x0020当用到 invokespecial 指令时,需要特殊处理的父类方法。
ACC_INTERFACE0x0200标识定义的是接口而不是类。
ACC_ABSTRACT0x0400不能被实例化。
ACC_SYNTHETIC0x1000标识并非 Java 源码生成的代码。
ACC_ANNOTATION0x2000标识注解类型
ACC_ENUM0x4000标识枚举类型

5.当前类索引

u2
指向当前类的在常量池项中的该类的索引

6.父类索引

u2
指向当前类的父类在常量池项中的该类的索引
用来确定这个类的父类的全限定名;
因为Java语言不允许多生继承,所以父类索引只有一个;并且除java.lang.Object外,其他所有类的父类索引都不能为0;
对于接口来说,索引指向的项必须为代表java.lang.Object的CONSTANT_Class_info类型常量;

7.接口索引集合

size项目
u2interfaces_count
u2interfaces

implements(接口extends)后实现的按顺序从左到右排列在接口索引集合;
如果没有实现任何接口,interfaces_count为0,后面不再有interfaces[interfaces_count];

8.字段表 Fields

字段表集合描述当前类或接口声明的所有字段;

field_info用于表示当前类或接口中某个字段的完整描述,包括类字段(static字段)或实例字段,不包括局部变量,但不包括从父类或父接口继承的部分字段;

对内部类,编译器可能自动添加对外部类实例的字段;

基本组成:

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

access_flag:
是用于定义字段被访问权限和基础属性的掩码标志;
和前面类的访问标志一样,没使用的需要设置为0;
有些标记是互斥的,如不能同时设置标志 ACC_FINAL 和 ACC_VOLATILE;
字段的access_flag表:

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_PRIVATE0x0002Declared private; usable only within the defining class.
ACC_PROTECTED0x0004Declared protected; may be accessed within subclasses.
ACC_STATIC0x0008Declared static.
ACC_FINAL0x0010Declared final; never directly assigned to after object construction (JLS §17.5).
ACC_VOLATILE0x0040Declared volatile; cannot be cached.
ACC_TRANSIENT0x0080Declared transient; not written or read by a persistent object manager.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ENUM0x4000Declared as an element of an enum.

attribute_info在后面详细展开

9.方法表

methods[]数组只描述当前类或接口中声明的方法;
包括实例方法、类方法、实例初始化方法方法和类或接口初始化方法方法;但不包括从父类或父接口继承的方法;
可能存在编译自动添加的方法,如类构造器"“和实例构造器”";
method_info用于表示当前类或接口中某个方法的完整描述;
如attributes[]中可能存在"Code"属性,表示方法逻辑代码编译后的字节码指令;

method_info {
    u2             access_flags;//用于定义当前方法的访问权限和基本属性的掩码标志;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

access_flags:
和前面类的访问标志一样,没使用的需要设置为0;
有些标记是互斥的,如不能同时设置标志 ACC_FINAL 和 ACC_ABSTRACT;
方法项的access_flags表:

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_PRIVATE0x0002Declared private; accessible only within the defining class.
ACC_PROTECTED0x0004Declared protected; may be accessed within subclasses.
ACC_STATIC0x0008Declared static.
ACC_FINAL0x0010Declared final; must not be overridden (§5.4.5).
ACC_SYNCHRONIZED0x0020Declared synchronized; invocation is wrapped by a monitor use.
ACC_BRIDGE0x0040A bridge method, generated by the compiler.
ACC_VARARGS0x0080Declared with variable number of arguments.
ACC_NATIVE0x0100Declared native; implemented in a language other than Java.
ACC_ABSTRACT0x0400Declared abstract; no implementation is provided.
ACC_STRICT0x0800Declared strictfp; floating-point mode is FP-strict.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.

attribute_info在后面详细展开

10.属性表

在Class文件的 ClassFile结构、字段表、方法表中都可以存储放自己的属性表集合,所以并不像最前面那Class文件结构那么直观,即属性不都是放在Class文件的最后;
属性表的通用格式:

attribute_info {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length];
}

不同属性的info是不同的,即attribute_name_index对应的类型有特定的属性格式
具体在 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.2 中,不多赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值