class类文件的结构(一)

Class文件格式

类型名称数量
u4magic1
u2minor_version1
u2major_version1
u2constant_pool_count1
cp_infoconstant_poolconstant_pool_count
u2access_flags1
u2this_class1
u2super_class1
u2Interfaces_count1
u2interfacesinterfaces_count
u2fields_count1
field_infofields1
u2methods_count1
method_infomethodsmethods_count
u2attributes_count1
attribute_infoattributesattributes_count

魔数与 Class文件的版本

魔数(magic):ca fe ba be
此版本(minor_version):00 00
主版本(major_version):00 34
在这里插入图片描述

常量池

常量池数据(constant_pool_count):0x16=22,由于第0个数字有其他含义,所有只有21个,就代表常量池中有21项常量,索引值范围为1~21。
在这里插入图片描述
常量池中主要存放两大类常量:字面量( Literal)和符号引用( Symbolic References)。字面量比较接近于Java语言层面的常量概念,如文本字符串、声明为fnal的常量等。而符号引用则属于编译原理方面的概念,包括了下面三类常量:

  • 类和接口的全限定名( Fully Qualified Name)
  • 字段的名称和描述符( Descriptor)
  • 方法的名称和描述符

常量池的项目类型

类型标志描述
CONSTANT_utf8_info1UTF-8编码的字符串
CONSTANT_Integer_info3整形字面量
CONSTANT_Float_info4浮点型字面量
CONSTANT_Long_info长整型字面量
CONSTANT_Double_info双精度浮点型字面量
CONSTANT_Class_info类或接口的符号引用
CONSTANT_String_info字符串类型字面量
CONSTANT_Fieldref_info字段的符号引用
CONSTANT_Methodref_info10类中方法的符号引用
CONSTANT_InterfaceMethodref_info11接口中方法的符号引用
CONSTANT_NameAndType_info12字段或方法的符号引用
CONSTANT_MothodType_info15标志方法类型
CONSTANT_MethodHandle_info16表示方法句柄
CONSTANT_InvokeDynamic_info18表示一个动态方法调用点

源文件

package com.test;

public class TestClass {
	private int m;
	
	public int getM() {
		return m + 2;
	}
	
}

使用 Javap命令输出常量表
javap -v class文件

javap -v com.test.TestClass
Classfile /C:/temp-workspace/ericsson-workspace/FCAPS_CM/target/classes/com/test/TestClass.class
  Last modified 2019-11-27; size 372 bytes
  MD5 checksum 523f379513308882e93adadf7024c6bb
  Compiled from "TestClass.java"
public class com.test.TestClass
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#18         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#19         // com/test/TestClass.m:I
   #3 = Class              #20            // com/test/TestClass
   #4 = Class              #21            // java/lang/Object
   #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               Lcom/test/TestClass;
  #14 = Utf8               getM
  #15 = Utf8               ()I
  #16 = Utf8               SourceFile
  #17 = Utf8               TestClass.java
  #18 = NameAndType        #7:#8          // "<init>":()V
  #19 = NameAndType        #5:#6          // m:I
  #20 = Utf8               com/test/TestClass
  #21 = Utf8               java/lang/Object
{
  public com.test.TestClass();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 15: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/test/TestClass;

  public int getM();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field m:I
         4: iconst_2
         5: iadd
         6: ireturn
      LineNumberTable:
        line 19: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  this   Lcom/test/TestClass;
}
SourceFile: "TestClass.java"

常量池中的14种常量项的结构总表

常量项目类型描述
CONSTANT_Utf8_infotagu1值为1
lengthu2UF-8编码的字符串占用的字节数
bytesu1长度为length的UTF-8编码的字符串
CONSTANT_Integer_infotagu1值为3
bytesu4按照高位在前存储的int值
CONSTANT_Float_infotagu1值为4
bytesu4按照高位在前存储的float值
CONSTANT_Long_infotagu1值为5
bytesu8按照高位在前存储的long值
CONSTANT_Double_infotagu1值为6
bytesu8按照高位在前存储的double值
CONSTANT_Class_infotagu1值为7
indexu2指向全限定名常量项的索引
CONSTANT_String_infotagu1值为8
indexu2指向字符串字面量的索引
CONSTANT_Fieldref_infotagu1值为9
indexu2指向声明字段的类或接口描述符CONSTANT_Class_info的索引项
indexu2指向字段名称及类型描述符CONSTANT_NameAndType_info的索引项
CONSTANT_Methodref_infotagu1值为10
indexu2指向声明方法的类描述符CONSTANT_Class_info的索引项
indexu2指向方法名称及类型描述符CONSTANT_NameAndType_info的索引项
CONSTANT_InrerfaceMethodref_infotagu1值为11
indexu2指向声明方法的接口描述符CONSTANT_Class_info的索引项
indexu2指向方法名称及类型描述符CONSTANT_NameAndType_info的索引项
CONSTANT_NameAndType_infotagu1值为12
indexu2指向字段或方法名称常量项目的索引
indexu2指向该字段或方法描述符常量项的索引
CONSTANT_Method-Handle_infotagu1值为15
reference_kindu1[1,9],决定了方法句柄的类型。方法句柄类型的值表示方法句柄的字节码行为
reference_indexu2值必须为常量池的有效索引
CONSTANT_Method-Type_infotagu1值为16
descriptor_indexu2值必须为常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,表示方法的描述符。
CONSTANT_Invoke-Dynamic_infotagu1值为18
bootstrap_method_attr_indexu2值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引
name_and_type_indexu2值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符

访问标志

类型名称数量
u2access_flags1

在常量池结束之后,紧接着的两个字节代表访问标志( access flags),这个标志用于识别一些类或者接口层次的访问信息,包括:这个Cas是类还是接口;是否定义为 public类型;是否定义为 abstract类型;如果是类的话,是否被声明为 final等。

标志名称标志值含义
ACC PUBLIC0x0001是否为 public类型
ACC FINAL0x0010是否被声明为 final,只有类可设置
ACC SUPER0x0020是否允许使用 invokespecial字节码指令的新语意, invokespecial指令的语意在JDK1.0.2发生过改变,为了区别这条指令使用哪种语意,JDK1.0.2之后编译出来的类的这个标志都必须为真
ACC INTERFACE0x0200标识这是一个接口
ACC ABSTRACT0x0400是否为 abstract类型,对于接口或者抽象类来说,此标志值为真,其他类值为假
ACC SYNTHETIC0x1000标识这个类并非由用户代码产生的
ACC ANNOTATION0x2000标识这是一个注解
ACC ENUM0x4000标识这是一个枚举

类索引、父类索引与接口索引集合

类型名称数量
u2this_class1
u2super_class1
u2Interfaces_count1

类索引( this class)和父类索引( super class)都一个u2类型的数据,而接口索引集合( interfaces)是一组u2类型的数据的集合, Class文件中由这三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名由于Java语言不允许多重继承,所以父类索引只有一个,除了 java. lang. Object之外,所有的Java类都有父类,因此除了 java. lang Object外,所有Java类的父类索引都不为0。接口索引集合就用来描述这个类实现了哪些接口,这些被实现的接口将按 implements语句(如果这个类本身是一个接口,则应当是 extends语句)后的接口顺序从左到右排列在接口索引集合中
类索引、父类索引和接曰索引集合都按顺序排列在访问标志之后,类索引和父类索引用两个u2类型的索引值表示,它们各自指向一个类型为 coNSTANT Class info的类描述符常量,通过CONSTANT_Class_info类型的常量中的索引值可以找到定义在CONSTANT_Utf8_info类型的常量中的全限定名字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值