java虚拟机规范(se8)——class文件格式(二)
4.4 常量池
java虚拟机指令并不依赖类、接口、类实例或者数组的运行时布局。相反,指令依靠常量池中的符号信息。
所有的常量池条目都有如下的通用结构:
cp_info {
u1 tag;
u1 info[];
}
常量池表中的每一个项目是以1比特的标识位开始,指示是哪种cp_info条目。info数组的内容由标志位来决定。有效的标识以及对应的值见表4.4-A。每个标识位后面必须跟2个或更多字节,这些字节给出了这些指定常量的信息。额外信息的格式由标识值来决定。
表4.4-A 常量池标识
Constant Type | Value |
---|---|
CONSTANT_Class |
7 |
CONSTANT_Fieldref |
9 |
CONSTANT_Methodref |
10 |
CONSTANT_InterfaceMethodref |
11 |
CONSTANT_String |
8 |
CONSTANT_Integer |
3 |
CONSTANT_Float |
4 |
CONSTANT_Long |
5 |
CONSTANT_Double |
6 |
CONSTANT_NameAndType |
12 |
CONSTANT_Utf8 |
1 |
CONSTANT_MethodHandle |
15 |
CONSTANT_MethodType |
16 |
CONSTANT_InvokeDynamic |
18 |
4.4.1 CONSTANT_Class_info结构
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
CONSTANT_Class_info结构的项目如下:
tag
标志位的值为CONSTANT_Class(7)。
name_index
name_index的值必须是常量池表中的一个有效索引。常量池在这个索引位置的条目必须是一个CONSTANT_Utf8_info结构,表示一个有效的二进制类或者接口名称,这个名称使用内部形式进行编码。
因为数组是对象,字节码anewarray和multianewarray(不包括字节码new)能够通过常量池中的CONSTANT_Class_info结构来引用一个数组“类”。对于这样的数组“类”,类的名称就是数组类型来的描述符(4.3.2)。
例如,二维数组类型int[][]的类名表示为[[I,然而Thread[]的类名表示为[Ljava/lang/Thread。
只有数组的维度为255或者更少时,数组类型描述符才是有效的
4.4.2 CONSTANT_Fieldred_info,CONSTANT_Methodref_info,以及CONTANT_InterfaceMethodref_info结构
字段,方法和接口方法使用相似的结构来表示:
CONSTANT_Fieldref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
} CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
} CONSTANT_InterfaceMethodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
这个结构的条目如下:
tag
CONTANT_Fieldref_info的tag值为CONSTANT_Fieldref(9)。
CONTANT_Methodref_info的tag值为CONSTANT_Methodref(10)。
CONTANT_InterfaceMethodref_info的tag值为CONSTANT_InterfaceMethodref(11)。
class_index
class_index的值必须是constant_pool表中的一个有效索引。索引位置的条目必须是一个CONSTANT_Class_info结构,表示一个有这个字段或者方法作为成员的类或者接口类型。
CONSTANT_Methodref_info结构的class_index必须是一个类类型,不能是接口类型
CONSTANT_InterfaceMethodref_info的class_index表示的条目必须是一个接口类型
CONSTANT_Fieldref_info结构的class_index条目可以是类类型或者接口类型。
name_and_type_index
name_and_type_index的值必须是constant_pool表中的一个有效索引。索引位置的条目必须是一个CONSTANT_NameAndType_info结构,指示这个字段或者方法的名称和描述符。
在CONSTANT_Fieldref_info中,指示的描述符必须是一个字段描述符。其它的必须是方法描述符。
如果CONSTANT_Methodref_info结构的方法的名称以'<' ('\u003c')开始,那么这个名称必须是特殊名称<init>表示一个实例的初始化方法。它的返回类型必须是void。
4.4.3 CONSTANT_String_info 结构
CONSTANT_String_info结构用来表示String类型的常量对象
CONSTANT_String_info {
u1 tag;
u2 string_index;
}
CONSTANT_String_info结构的项目如下:
tag
CONSTANT_String_info的tag值为CONSTANT_String(8)。
string_index
class_index的值必须是constant_pool表中的一个有效索引。索引位置的条目必须是一个CONSTANT_Utf8_info结构,表示需要初始化的String对象的Unicode代码点的序列。
4.4.4 CONSTANT_Integer_info和CONSTANT_Float_info结构
CONSTANT_Integer_info和CONSTANT_Float_info结构表示4字节数值常量(int 和 float)。
CONSTANT_Integer_info {
u1 tag;
u4 bytes;
} CONSTANT_Float_info {
u1 tag;
u4 bytes;
}
这些架构的项目如下:
tag
CONSTANT_Integer_info结构的tag值为CONSTANT_Integer(3).
CONSTANT_Float_info结构的tag值为CONSTANT_Float(4).
bytes
CONSTANT_Integer_info的bytes项目表示int常量的值,int值的字节存储为大端模式。
CONSTANT_Float_info的bytes项目表示float常量的值,使用IEEE 754单精度浮点格式。单精度格式的字节存储为大端模式。
CONSTANT_Float_info结构表示的值由下面这些规则决定。值的字节首先按照int形式转换,然后:
1、如果转换的比特位为0x7f800000,那么float的值为正无穷大
2、如果转换的比特位为0xff800000,那么float的值为负无穷大
3、如果转换的比特位在0x7f800001到0x7fffffff或者在0xff800001到0xffffffff之间,那么float的值为NaN。
4、其它情况下,flaot的值根据比特位计算如下:
int s = ((bits >> 31) == 0) ? 1 : -1;
int e = ((bits >> 23) & 0xff);
int m = (e == 0) ?
(bits & 0x7fffff) << 1 :
(bits & 0x7fffff) | 0x800000;
那么float的值等于数学表达式s · m · 2e-150
.的结果
4.4.6 CONSTANT_NameAndType_info结构
CONSTANT_NameAndType_info结构用来表示字段和方法,但是不指明属于哪个类或者接口类型:
CONSTANT_NameAndType_info {
u1 tag;
u2 name_index;
u2 descriptor_index;
}
CONSTANT_NameAndType_info结构的项目如下:
tag
CONSTANT_NameAndType_info结构的tag项目的值为CONSTANT_NameAndType(12).
name_index
name_index的值必须是常量池表中的有效索引。这个索引位置必须是一个CONSTANT_Utf8_info结构,表示一个特殊的方法名<init>或者一个有效的非限定名称指示一个字段或者方法。
desciptor_index
name_index的值必须是常量池表中的有效索引。这个索引位置必须是一个CONSTANT_Utf8_info结构,表示一个有效的字段描述符或者方法描述符。
4.4.7 CONSTANT_Utf8_info结构
CONSTANT_Utf8_info结构用来表示一个字符串常量值:
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
结构中的项目如下:
tag
CONSTANT_Utf8_info的tag值为CONSTANT_Utf8(1).
length
length的值bytes数组中字节的数量(不是string的长度)。
bytes[]
bytes数组包含的字符串的字节。
字节的值不能为(byte)0
字节的值不能为(byte)0xf0 到 (byte)0xff.
字符串的内容使用修正的UTF-8编码。使用修正的UTF-8编码以便每个代码点仅使用一个字节来表示仅包含非空ASCII字符的代码点序列,也可以表示Unicode代码空间的所有代码点。修正的UTF-8不以空值结束。编码过程如下:
代码点在'\u0001' 到 '\u007F'范围间,使用一个单独的字节来表示:
0 | bits 6-0 |
7位的数值给出了代码点表示的值。
null代码点('\u0000')和代码点在'\u0080'到'\u07FF'范围的使用一对字节x和y来表示:
x:
1 | 1 | 0 | bits 10-6 |
y:
1 | 0 | bits 5-0 |
这两个字节的代码点的值为:
((x & 0x1f) << 6) + (y & 0x3f)
代码点在'\u0800'到 '\uFFFF'范围的使用三个字节x,y,z来表示:
x:
1 | 1 | 1 | 0 | bits 15-12 |
y:
1 | 0 | bits 11-6 |
1 | 0 | bits 5-0 |
((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f)
代码点高于U + FFFF的字符(所谓的补充字符)通过分别编码其UTF-16表示的两个代理代码单元来表示。每个代理代码单元由三个字节表示。这意味着补充字符由六个字节u,v,w,x,y和z表示:
u : |
|
||||||||
v : |
|
||||||||
w : |
|
||||||||
x : |
|
||||||||
y : |
|
||||||||
z : |
|
六字节表示的代码点的值为:
0x10000 + ((v & 0x0f) << 16) + ((w & 0x3f) << 10) +
((y & 0x0f) << 6) + (z & 0x3f)
多字节字符的字节以大端模式(高字节优先)顺序存储在类文件中。
这种格式与“标准”UTF-8格式有两点不同。首先,使用2字节格式而不是1字节格式对空字符(char)0进行编码,以便修正的UTF-8字符串永远不会嵌入空值。其次,仅使用标准UTF-8的1字节,2字节和3字节格式。 Java虚拟机无法识别标准UTF-8的四字节格式;它使用自己的2*三字节格式。
java虚拟机规范(se8)——class文件格式(二)的更多相关文章
- java虚拟机规范(se8)——class文件格式(四)
4.7 属性 属性用于class文件格式中的ClassFile,field_info,method_info和Code_attribute结构. 所有的属性都是下面的格式: attribute_inf ...
- java虚拟机规范(se8)——class文件格式(一)
第四章 class文件格式 本章介绍了java虚拟机的class文件格式.每一个class文件包含一个单独的类或者接口的定义.虽然类和接口不一定都定义在文件中(比如类和接口亦可以通过类加载器直接生成) ...
- java虚拟机规范(se8)——class文件格式(五)
4.7.1 定义和命名新属性 允许编译器定义和发布的class文件在class文件结构体.field_info结构体.method_info结构体和Code结构体中的attributes表中包含新的属 ...
- java虚拟机规范(se8)——class文件格式(三)
4.5 字段 字段使用field_info结构来描述. 在同一个class文件中的两个字段不能有相同的名称和描述符. 结构的格式如下: field_info { u2 access_flags; u2 ...
- java虚拟机规范(se8)——class文件格式(七)
4.7.5 Exceptions 属性 Exceptions 属性是一个变长属性,它位于 method_info(§4.6)结构的属性表中. Exceptions 属性指出了一个方法需要检查的可能抛出 ...
- java虚拟机规范(se8)——class文件格式(六)
4.7.4 StackMapTable 属性 StackMapTable 属性是一个变长属性,位于 Code(§4.7.3)属性的属性表中.这个属性会在虚拟机类加载的类型阶段(§4.10.1)被使用. ...
- java虚拟机规范(se8)——java虚拟机结构(一)
本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述 ...
- java虚拟机规范(se8)——java虚拟机结构(二)
2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区 ...
- java虚拟机规范(se8)——java虚拟机的编译(二)
3.3 算术运算 java虚拟机通常在操作数栈上进行算术运算(例外情况是iinc指令,它直接增加一个局部变量的值).例如下面的align2grain()方法,它的作用是将int值对齐到2的指定次幂: ...
随机推荐
- 常见前端HTML5面试题
1.H5新标签新特性 新标签:header,nav,footer,aside,article,section,Canvas,audio,video 新特性:localStorag, sessionSt ...
- 读书笔记一、pandas数据结构介绍
pandas数据结构介绍 主要两种数据结构:Series和DataFrame. Series Series是一种类似于一维数组的对象,由一组数据(各种NumPy数据类型)+数据标签(即索引)组 ...
- Codeforces 963E Alternating Sum 等比数列+逆元
题目大意: 看一下样例就明白了 基本思路: 题目中明确提到k为一个周期,稍作思考,把k项看作一项,然后发现这是个等比数列,q=(b/a)^k, 然后重点就是怎样处理等比数列求和表达式中的除法,这个时候 ...
- Yii Ar model 查询
Ar model 查询 参照表: CREATE TABLE tbl_user ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, username VA ...
- sql查询时间范围
select * from table where Time>='2019-05-09 00:05:36' and Time<='2019-05-10 00:05:36'
- YOLOv1算法理解
1,YOLOv1算法的简介 YOLO算法使用深度神经网络进行对象的位置检测以及分类,主要的特点是速度够快,而且准确率也很高,采用直接预测目标对象的边界框的方法,将候选区和对象识别这两个阶段合二为一, ...
- 前端-SuperSlide自动分页控制、自适应轮播图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JMeter生成UUID方式
1. 使用JMeter工具中自带的函数__UUID 2. 使用Beanshell组件,在脚本中引入java.util.UUID,通过java来生成 import java.util.UUID; UUI ...
- fileupload组件之上传与下载的页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- DIV 粘贴插入文本或者其他元素后,移动光标到最新处
此文主要是可编辑div光标位置处理 1:首先 设置一个可编辑的DIV,注意:设置 contenteditable="true" 才可以编辑DIV <div id=" ...