分享
 
 
 

第六章 Java类文件(Chapter Six: The Java Class File)

王朝java/jsp·作者佚名  2006-12-30
窄屏简体版  字體: |||超大  

一、什么是Java类文件

Java类文件是Java程序的二进制表示形式。每一个类文件代表一个类或者接口。不可能在一个类文件中放入多个类或者接口。这样就使得无论类文件是在哪一种平台上生成,都可以在任何主机上执行。

虽然类文件是Java体系结构的一部分,但是他并不是与Java语言不可分的。你可以将其他语言的程序编译为类文件,也可以将Java程序文件编译为其他二进制形式。

Java类文件是一个基于8-bit字节的二进制流。数据块顺序的、无分割符的、big-endian的形式存储。

二、类文件的内容

Java的类文件中包含了所有Java虚拟机所需要的关于类和接口的信息。所有类文件中的信息都以以下的四种基本类型的存储:

Table 6-1. Class file "primitive types"

u1 a single unsigned byte

u2 two unsigned bytes

u4 four unsigned bytes

u8 eight unsigned bytes

类文件中的主要部分以表6-2的顺序存储:

Table 6-2. Format of a ClassFile Table

Type& #9;Name Count

u4 magic 1

u2 minor_version 1

u2 major_version 1

u2 constant_pool_count 1

cp_info constant_pool constant_pool_count-1

u2 access_flags 1

u2 this_class 1

u2 super_class 1

u2 interfaces_count 1

u2 interfaces interfaces_count

u2 fields_count 1

field_info fields fields_count

u2 methods_count 1

method_info methods methods_count

u2 attributes_count 1

attribute_info attributes attributes_count

1、魔术编码(magic)

每一个Java类文件的开头四个字节都是魔术编码(OxCAFEBABE)。通过魔术编码可以很容易识别类文件。

2、副版本号和主版本号(minor_version and major_version)

剩下的四个字节是副版本号和主版本号。但Java技术在进化时,一些新的特性可能会被加入到类文件中。每一次类文件格式的变化,都会相应的改变版本号。虚 拟机通过版本号来识别自己能够处理的类文件。Java虚拟机往往只能处理一个给定的主版本号和其下的一些副版本号。虚拟机必须拒绝那些不再处理范围内的类 文件。

3、常量个数和常量池(constant_pool_count and constant_pool)

接下来的就是常量池,常量池中包含了哪些被类或者接口访问过的常量,比如:字符串,常量(final variable values),类名,方法名。常量池作为一个列表存储。列表中常量的个数就是之前保存的“constant_pool_count”。

很多常量池中的常量都引用了常量池中的其他常量,那些引用常量池常量的引用最终也会转换为对常量池中常量的直接引用。虽然常量列表中的索引是从1开始的,但是常量个数还是包含了0,比如一个常量列表中有15个常量,那么它的常量个数就为16。

每一个常量开头都会有一个标志,以表示他的类型。当虚拟机读取这个标志时,就会知道这个常量的具体类型了。表6-3列举了这些标志:

Table 6-3. Constant pool tags

Entry Type Tag Value Description

CONSTANT_Utf8 1 A UTF-8 encoded Unicode string

CONSTANT_Integer 3 An int literal value

CONSTANT_Float 4 A float literal value

CONSTANT_Long 5 A long literal value

CONSTANT_Double 6 A double literal value

CONSTANT_Class 7 A symbolic reference to a class or interface

CONSTANT_String 8 A String literal value

CONSTANT_Fieldref 9 A symbolic reference to a field

CONSTANT_Methodref 10 A symbolic reference to a method declared in a class

CONSTANT_InterfaceMethodref 11 A symbolic reference to a method declared in an interface

CONSTANT_NameAndType 12 Part of a symbolic reference to a field or method

表6-3中的每一个标志都会有一个相应的表格,用来描述这个标志的所表示的一些详细信息,这些对应的标志都会以标志名+_INFO来结尾。比如CONSTANT_CLASS标志对应的就是CONSTANT_CLASS_INFO。

常量池在程序的动态链接中扮演了很重要的角色。除了上边所说的各种常量值以外,常量池中包含了一下三种符号引用:类和接口的全名,字段名和描述符,方法名 和描述符。一个字段是一个类或者接口中的实例或者类变量,字段描述符是字段的类型。方法的描述符是方法和返回值和参数的个数、顺序和类型。在虚拟机将这个 类或者接口链接到其他类或者接口时用到这些全名。因为类文件不包含任何关于内存结构的信息,所以这个链接只能以符号引用的形式存在。虚拟机在执行时将这些 符号引用转换为实际的地址。具体的信息参见第八章“The Linking Model”。

4、访问标志(access_flags)

紧接在常量池后面的两个字节就是访问标志,表示这个类或者接口的几方面信息,他有如下几种值:

Table 6-4. Flag bits in the access_flags item of ClassFile tables

Flag Name Value Meaning if Set Set By

ACC_PUBLIC 0x0001 Type is public Classes and interfaces

ACC_FINAL 0x0010 Class is final Classes only

ACC_SUPER 0x0020 Use new invokespecial semanticsClasses and interfaces

ACC_INTERFACE 0x0200 Type is an interface, not a class All interfaces, no classes

ACC_ABSTRACT 0x0400 Type is abstract All interfaces, some classes

ACC_SUPER标志是为了兼容以前SUN的老式的编译器。所有没有使用的访问标志,必须设置为0。

5、类名(this_class)

接下来的两个字节保存了一个常量池的索引。这个常量池中的实体必须是CONSTANT_CLSS_INTO类型的,他包含了标志和名字索引。标志就是 CONSTATN_CLASS,那个名字索引应该是一个保存了这个类或者接口全名的CONSTANT_UTF8_INFO类型的索引。

6、父类(super_class)

this_class之后的就是两个字节的super_class,他也是一个常量池的索引,其中保存了父类的全名,处理this_class一样。当父 类是java.lang.Object时,super_class都应该是0。对于接口super_class都是0。

7、(interfaces_count and interfaces)

interfaces_count中保存了父接口的个数,interfaces中以数组形式保存了一些常量池的索引。每一个索引都指向了一个 CONSTANT_CLASS_INFO的常量,其中保存了每一个父接口的全名。这个数组的顺序就是父接口出现在在implements、extends 语句中从左到右的顺序。

8、(fields_count and fields)

字段被保存在一个field_info的列表中,fields_count是这个列表的长度。Field_info列表中保存的只是类或者接口中的申明的变量,从父类或者父接口中继承的字段不保存在这里。

每一个field_info表中的一条都描述了一个字段的信息,包括:字段名,描述符,访问权限。如果一个字段被申明为final,那么这个字段的信息即会保存在field_info表中,也会保存在常量池中。

9、(methods_count and methods)

方法的信息都保存在method_info表中,mehtods_count是表的长度。Method_info表中只保存类或者接口中申明的方法,不保存从父类或者接口中继承的方法。

Method_info 表中保存了方法名和描述符(返回值和参数类型)。如果不是抽象方法,还会保存用于堆栈的大小(保存本地变量用的)、操作数堆栈的最大值、捕捉的异常列表、 方法的字节码、可选的行号和本地变量表。如果方法抛出一些被检查的异常,method_info还会包含一个被检查异常的列表。

10、(attributes_count and attributes)

类文件中最后的就是属性个数和atribute_info列表。Atribute_info表中保存了一些指向常量池中constant_utf8_info的索引,其中保存了属性的名字。Java虚拟机规范中定义了两种类型的属性:源代码和内部类。

三、特定字符串(Special Strings)

常量池中的字符引用包含三种特定字符串:全限定名,简单名,描述符。一个类或者接口的所有字符引用都必须包含一个全限定名。每一个字段或者方法都有一个简 单名和描述符作为全限定名的补充。这些特定字符串用来表示文件中定义的类和接口,包换类名,父类名,父接口名,每个字段和方法的简单名和描述符。

1、全名(Fully Qualified Names)

当常量池中引用了类和接口时,就会提供这个类或者接口的权限定名,比如java.lang.Object。

2、简单名(Simple Names)

字段和方法都以简单名的形式保存在常量池中。比如常量池中有一个java.lang.Object类的String toString()方法的引用,就会保存“toString”;java.lang.System类的java.io.PrintStream out字段,被保存为“out”。

3、描述符(Descripters)

字段和方法的字符引用都会包含一个描述符。字段的描述符提供了字段的类型。方法的描述符提供了方法的返回值、参数个数、参数类型。所有描述符得类型列表:

FieldDescriptor:

FieldType

ComponentType:

FieldType

FieldType:

BaseType

ObjectType

ArrayType

BaseType:

Terminal Type

B byte

C char

D double

F float

I int

J long

S short

Z boolean

ObjectType:

L<classname>;

ArrayType:

[ ComponentType

ParameterDescriptor:

FieldType

MethodDescriptor:

( ParameterDescriptor* ) ReturnDescriptor

ReturnDescriptor:

FieldType

V

Table 6-6. Examples of field descriptors

Descriptor Field Declaration

I int i;

[[J long[][] windingRoad;

[Ljava/lang/Object; java.lang.Object[] stuff;

Ljava/util/Hashtable; java.util.Hashtable ht;

[[[Z boolean[][][] isReady;

Table 6-7. Examples of method descriptors

Descriptor Method Declaration

()I int getSize();

()Ljava/lang/String; String toString();

([Ljava/lang/String;)V void main(String[] args);

()V void wait()

(JI)V void wait(long timeout, int nanos)

(ZILjava/lang/String;II)Z boolean regionMatches(boolean ignoreCase, int toOffset, String other, int ooffset, int len);

([BII)I int read(byte[] b, int off, int len);

四、常量池

常量池被组织成为一个cp_info类型的列表,表6-8显示了cp_info表的结构

Table 6-8. General form of a cp_info table

Type Name Count

u1 tag 1

u1 info depends on tag value

1、The CONSTANT_Utf8_info Table

2、The CONSTANT_Integer_info Table

3、The CONSTANT_Float_info Table

4、The CONSTANT_Long_info Table

5、The CONSTANt_Double_info Table

6、The CONSTANT_Class_info Table

7、The CONSTANT_String_info Table

8、The CONSTANT_Fieldref_info Table

9、The CONSTANT_Methodref_info Table

10、The COMSTANT_InterfaceMethodref_info Table

11、The CONSTANT_NameAndType_info Table

五、Fields

六、Methods

七、Attributes

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有