当前位置: 首页 > 工具软件 > jvms > 使用案例 >

JVMS-class文件格式-2【转载】

尉迟雅昶
2023-12-01
http://www.i170.com/Forum/113657
花了10多个小时,才将JVMS- class File Format-走一遍  ,虽然针对的是最简单的AAA。意义何在?

1、对class文件格式有了整体认识,看CHAPTER 4 The class File Format已经是简单的事情了;

2、使用字节码察看工具,知道了其各项的对应关系。

3、补了一课,解开了一个心结。

 

CHAPTER 4 The class File Format

pseudostructures:在class文件中是不存在的,一种方便的说明方式。它有多个items,Successive items are stored in the class file sequentially, without padding or alignment. 所以,有一些说明本结构长度的项,如constant_pool_count等等各种xxx_count。

Tables是varying-sized structures ,而an array有fixed-sized items 。

4.1 The ClassFile Structure

    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];
    }
这个大图分7段,核心在cp_info 、field_info、method_info和多处使用的attribute_info。

本节比较重要的部分:

1、前10字节:JDK1.0.2中编译的class文件版本号为3.45,version0.50。

2、u2 constant_pool_count 最基本的值为16(事实上15项),其中第0项被隐藏。添加一些代码后,可以研究一下cp_info的变动情况。constant_pool table的排列有一定的顺序。这是重点。

3、中间字节:类的access_flags ,各种修饰符求或;this_class、super_class等等信息都要在constant_pool中找。

4、field_info、method_info和attribute_info,添加一些代码后使用jclasslib研究一下。

 

4.2 The Internal Form of Fully Qualified Class and Interface Names

class文件总是采用fully qualified form 的类型名,所以import语句都是语法糖;java.lang.Object转成了/分割。

4.3 Descriptors

A descriptor using UTF-8 strings (§4.4.7)表示the type of a field or method.

4.4 The Constant Pool

 

严格地,class文件中只有constant_pool table,而常量池是运行期的一个内存空间。当然JVM 指令不依赖类/接口/类实例/数组在运行时的布局,仅仅依赖于本constant_pool table中的字符信息(symbolic information )。

各种constant_pool table实体/条目(entries)由一个u1即1-byte tag来区别,以便使用相应的结构。

public class Yqj{
    public static int i = 5;
    private final double doo = 5.2;
    String str = "hello";
    public Object foo(){
        int iiiiii = 100;
        return "hello";
    }
}
这个程序较AAA复杂得多,37-1项constant_pool table条目。常量池表的index-tag-解释

1、CONSTANT_Methodref (10)这总是第一个条目。共5u

2、CONSTANT_Double (6).表示它占用2个#以组成一个double常量5.2,共9u

4、CONSTANT_Fieldref (9),由#8和#31描述本成员变量即Yqj,dooD,共5u

5、CONSTANT_String (8).其string_index指向CONSTANT_Utf8_info 结构#32,那是它将被初始化的值。3u

6、CONSTANT_Fieldref (9),由#8和#33描述本成员变量即Yqj,strLjava/lang/String

7、CONSTANT_Fieldref (9),由#8和#34描述本成员变量即Yqj,iI

8、CONSTANT_Class (7).由#35描述类信息Yqj。3u

9、CONSTANT_Class (7).由#36描述类信息java/lang/String。3u

10-29,CONSTANT_Utf8 (1).各种保存Utf8字符串的结构。分别是:

#10(i),#11(I),#12(doo),#13(D),#14(ConstantValue),

#15(str),#16(Ljava/lang/String),#17(<init>),#18(()V),#19(Code),

#20(LineNumberTable),#21(LocalVariableTable),#22(this),#23(Lyqj),

#24(foo),#25(()Ljava/lang/Object),#26(iiiiii),#27(<clinit>),

#28(SourceFile),#29(Yqj.java),

30、CONSTANT_NameAndType (12).由#17,#18说明的信息,<init>和()V

31、CONSTANT_NameAndType (12).由#12,#13说明的信息,<doo>和D

32、CONSTANT_Utf8 (1).hello

33、CONSTANT_NameAndType (12).由#15,#16说明的信息,str和Ljava/lang/String

34、CONSTANT_NameAndType (12).由#10,#11说明的信息,i和I

35、CONSTANT_Utf8 (1).Yqj

36、CONSTANT_Utf8 (1).java/lang/String

除了JVM中预定义的字符串(java/lang/String、<init>、()V、I、SourceFile等等)、表示成员的标识符(LYqj、i、doo、iiiiii、foo),程序中定义的命名常量的值5.2CONSTANT_Double,字符串常量#32的CONSTANT_Utf8 被列入constant_pool table。

 

Note: LocalVariableTable is not a necessary attribute. Some compilers even do not generate a LocalVariableTable in .class files, e.g. the jdk 1.4.2_11.

 

 类似资料: