类文件结构

1. Java一次编写,到处执行的基石:

   Java编译产生的是字节码(bytecode)。sun公司和其它虚拟机提供商公布各个平台上的虚拟机。这些虚拟机能够加载和执行这些与平台无关的字节码。

2. Class类文件结构:

Class文件是一组以字节为基础单位的二进制字节流,各个数据项目严格依照顺序紧凑的排列在class文件之中。中间没有不论什么分隔符。

Class文件使用无符号数和表来存储全部的数据。

无符号数属于基本数据类型,用u1、u2、u4、u8来代表1个字节、2个字节、4个字节和8个字节的无符号数;表是由多个无符号数和其它表构成的符合数据类型。

整个class文件本质上就是一张表。它的数据项例如以下:

Class文件的格式

不管是无符号数还是表。当要描写叙述同一类型但数量不定的多个数据的时候,常常会使用一个前置的容量计数器加若干连续的数据项的形式。称为一个集合。

这里须要重点声明一下的是,Class文件没有不论什么的分隔符,所以上图中的全部数据项,不管是顺序还是数量,甚至数据存储的字节序,都被严格限定,不同意改变。

 

Class文件里的常量池:常量池是class文件的资源仓库。存放两类常量:字面量和符号引用。字面量包含文本字符串、声明为final的常量。符号引用包含:①类和接口的全限定名、②字段的名称和描写叙述符、③方法的名称和描写叙述符。常量池的每一项常量都是一个表,一共14中表结构。比如:

Constant_Class_info型常量的结构

常量池并没有固定的结构,它仅仅是一个资源仓库,想查找它里面的内容仅仅需提供索引值就可以。

Class文件里的类索引、父类索引、接口索引集合:类索引和父类索引都是一个u2类型的数据,它们都有且仅仅有一个(由于java不同意多继承),他们的值都是指向常量池中对应项的一个索引值。接口索引集合入口的第一项是接口索引的数量。后面是一系列u2类型的索引指向常量池中的对应值的索引。

 

字段表集合:字段表用于描写叙述类或接口中声明的变量。

字段表的结构例如以下:

字段表结构

这些属性按access_flags、name_index、descriptor_index、attributes_count、attributes的顺序排列。

⑴access_flags存储字段修饰符,跟类中的access_flags很相似,都是一个u2的数据类型,当中能够设置的标志位和含义例如以下:

字段訪问标志

⑵name_index存储对常量池的索引。代表字段的简单名称。

⑶descriptor_index存储对常量池的索引,存储字段的描写叙述符。关于简单名称、描写叙述符、全限定名,这里做一个介绍例如以下:

①简单名称就是没有类型和參数修饰的方法或字段的名称。如inc()方法和m字段的简单名称就是inc和m。

②全限定名很好理解。类的全限定名就是包1.包2….类名。在class文件里不用.的ascii码而是用的/作分隔符。也就是包1/包2/…/类名;

③描写叙述符比較复杂,描写叙述符的作用是描写叙述字段的数据类型、方法的參数列表(包含数量、类型和顺序)和返回值,基本数据类型及void用一个大写字符来表示。对象类型用L加对象的全限定名来表示,详细例如以下:

描写叙述符标识字符含义

对于数组类型,每个维度用一个前置的[字符来描写叙述。比如java.lang.String[][]类型的二维数组会被记录为[[Ljava/lang/String;,int[]型数组会被记录为[I。用描写叙述符描写叙述方法时,依照先參数列表、后返回值的顺序描写叙述,參数列表依照參数的严格顺序存放在()之内,比如void inc()描写叙述符为()V。java.lang.String toString()描写叙述符为()Ljava/lang/String;,intindexOf(char[] source,
int sourceOffset, int sourceCount, char[] target, inttargetOffset, int targetCount, int fromIndex)的描写叙述符为([CII[CIII)I。

⑷在descriptor_index之后尾随着一个属性表集合用来存储一些额外的信息。

字段表集合不会列出从超类或者父接口中继承而来的字段。但有可能列出原Java代码中不存在的字段。如内部类为了保持对外部类的訪问性会自己主动加入指向外部类实例的字段。

 

方法表集合:方法表的结构和字段表相似,例如以下:

方法表结构

这些数据项目的含义也很相似,仅在訪问标志和属性表集合的可选项中有所区别。

方法訪问标志

方法的定义能够通过訪问标志、名称索引、描写叙述符索引表达清楚。那么方法的代码那里去了呢?方法里的Java代码。经过编译器编译成字节码指令后,存放在方法属性表中一个名为Code的属性里面。假设父类的方法没有被子类覆盖,则方法表集合中不会出现父类的方法信息。但相同的,有可能出现编译器自己主动加入的方法,如类构造器<cinit>方法和实例构造器<init>方法。

 

属性表集合:属性表用来描写叙述场景专有的信息。

属性表不须要具有严格的顺序,对于每个属性。它的名称须要从常量池中引用一个Constant_Utf8_info类型的常量来表示,而属性值的结构则是全然自己定义的,仅仅须要用一个u4类型的数据去说明属性值所占用的位数就可以,属性表结构例如以下:

属性表结构:

典型的属性。如Code,其结构例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

3. 字节码指令:

Java虚拟机的指令由一字节长度的操作码加零至多个操作数组成。

 

《深入理解jvm》笔记---第六章的更多相关文章

  1. 深入理解 C 指针阅读笔记 -- 第六章

    Chapter6.h #ifndef __CHAPTER_6_ #define __CHAPTER_6_ /*<深入理解C指针>学习笔记 -- 第六章*/ typedef struct _ ...

  2. JVM学习笔记-第六章-类文件结构

    JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...

  3. Android群英传笔记——第六章:Android绘图机制与处理技巧

    Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...

  4. 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(1)

    <Microsoft Sql server 2008 Internals>索引文件夹: <Microsoft Sql server 2008 Internals>读书笔记--文 ...

  5. 韩松毕业论文笔记-第六章-EFFICIENT METHODS AND HARDWARE FOR DEEP LEARNING

    难得跟了一次热点,从看到论文到现在已经过了快三周了,又安排了其他方向,觉得再不写又像之前读过的N多篇一样被遗忘在角落,还是先写吧,虽然有些地方还没琢磨透,但是paper总是这样吧,毕竟没有亲手实现一下 ...

  6. 《图解HTTP》阅读笔记--第六章--HTTP首部

    第六章.HTTP首部 <非常重要且恐怖的一章了> HTTP报文=报文首部+(CR+LF)+报文实体 首部字段:HTTP报文首部字段=(首部字段名:字段值)们---类型*4: 通用首部字段( ...

  7. oranges 笔记第六章

    OS 第六次实验随笔 第六章6.1-6.3相关的问题 进程状态保存与恢复 哪些状态 何时保存 保存在哪 如何恢复 特权级变换 用户进程到内核 内核回到用户进程 再次理解TSS .堆栈 从外环进入内环( ...

  8. C Primer Plus 学习笔记 -- 前六章

    记录自己学习C Primer Plus的学习笔记 第一章 C语言高效在于C语言通常是汇编语言才具有的微调控能力设计的一系列内部指令 C不是面向对象编程 编译器把源代码转化成中间代码,链接器把中间代码和 ...

  9. C primer plus 读书笔记第六章和第七章

    这两章的标题是C控制语句:循环以及C控制语句:分支和跳转.之所以一起讲,是因为这两章内容都是讲控制语句. 第六章的第一段示例代码 /* summing.c --对用户输入的整数求和 */ #inclu ...

  10. [CSAPP笔记][第六章存储器层次结构]

    第六章 存储器层次结构 在简单模型中,存储器系统是一个线性的字节数组,CPU能够在一个常数访问每个存储器位置. 虽然是一个行之有效的模型,但没有反应现代系统实际工作方式. 实际上,存储器系统(memo ...

随机推荐

  1. Windows虚拟内存不足问题的处理

    一般而言,当系统缺少虚拟内存会引起很多问题,包含但不限于: 操作系统运行缓慢,甚至出现Hang(夯机),蓝色背景界面的情况 用户本地控制台输入用户名.密码后,无法登录到操作系统,卡在欢迎界面 无法远程 ...

  2. Linux Shell 下载网站指定文件

    Shell脚本,用来从网站下载指定文件名的文件.先判断本地这个文件是否存在,如果存在则忽略,不存在则从远程服务器上下载,下载成功后本地的批次号累加1,然后使用新的批次号继续下载新文件. #!/bin/ ...

  3. python 模块之platform模块(基本了解)

    # -*- coding: cp936 -*-#python 27#xiaodeng#python 模块之platform模块(基本了解)#获取底层平台的识别数据 #知道该模块用途即可,需要使用时直接 ...

  4. 远程过程调用协议(RPC)

      RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的 ...

  5. 转:OGRE 源码编译方法

    编译及运行环境:Windows 7 . vs2010. 编译前的准备: 1.想编译OGRE,最起码要有OGRE的源码吧.可以去官方网站下载最新的源码包,我这里用的是1.7.2版本的,下载下来的文件叫 ...

  6. Retrofit使用指南

    Retrofit is a type-safe HTTP client for Android and Java. Retrofit是面向Android和Java平台的一个类型安全的HTTP客户端. ...

  7. Deep Introduction to Go Interfaces.

    Standard Interface Intro Go’s interfaces are one of it’s best features, but they’re also one of the ...

  8. Git提交代码报错Git push error:src refspec XXX matches more than one解决方案

    Git提交代码push时,报错这个 error: src refspec master matches more than one. error: failed to push some refs t ...

  9. ILP32、ILP64、LP64、LLP64、64位系统

    Data Type     ILP32      ILP64     LP64      LLP64char              8             8            8     ...

  10. ThinkPHP+jQuery EasyUI Datagrid查询数据的简单处理

    ThinkPHP和jQuery EasyUI这两个都是不错的框架,现在要把它两个整合到一块,做个简单的Ajax调用查询. 在ThinkPHP模板中引入EasyUI的相关文件,然后设置按钮3的调用: & ...