Class类文件的结构

  各种不同平台的虚拟机与所有平台都统一使用的程序存储格式---字节码(ByteCode)是构成平台无关性的基石。Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。

  魔数(Magic Number):Class文件的头4个字节,唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件。

  常量池(Constant Pool):是Class文件之中的资源仓库,是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时它还是在Class文件中第一个出现的表类型数据项目。常量池的容量计数是从1开始,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都是从0开始。常量池中主要存放字面量(Literal)和符号引用(Symbolic References)(符号引用包括类和接口的全限定名(Fully Qualified Name)、字段的名称和描述符(Descriptor)、方法的名称和描述符)。

  访问标志(Access Flags):占用两个字节,用于识别一些类或接口层次的访问信息。如这个Class是类还是接口,是否定义为public类型,是否定义为abstract类型,如果是类的话,是否被声明为final等。

  类索引(this_class)、父类索引(super_class)与接口索引集合(interfaces):类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,接口索引集合用来描述这个类实现了哪些接口。

  字段表集合(field_info):用于描述接口或者类中声明的变量。字段包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。

  方法表集合:与字段的描述几乎完全一致,结构如同字段表一样,依次包括访问标志(access_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)。

  属性表集合:在Class文件、字段表、方法表中都可以携带自己的属性表集合,以用于描述某些场景专有的信息。属性表集合不要求各个属性具有严格顺序,只要不与已有属性名重复即可,Java虚拟机运行时会忽略掉它不认识的属性。关键常用属性有:Code属性、Exceptions属性、LineNumberTable属性、LocalVariableTable属性、SourceFile属性、ConstantValue属性、InnerClasses属性、Deprecated及Synthetic属性、StackMapTable属性、Signature属性、BootstrapMethods属性。

公有设计和私有实现:公有设计指的是规定的Java虚拟机规范;私有实现是指在满足虚拟机规范的约束下对具体实现做出修改和优化以实现一个优秀的虚拟机。只要优化后Class文件依然可以被正确读取,并且包含在其中的语义能得到完整的保持,那实现者就可以选择任何方式去实现这些语义。虚拟机实现的方式主要有两种:(1)将输入的Java虚拟机代码在加载或执行时翻译成另外一种虚拟机的指令集;(2)将输入的Java虚拟机代码在加载或执行时翻译成宿主机CPU的本地指令集(即JIT代码生成技术)。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java 源码分析

Bootstrap 源码分析

Netty 源码分析: Bootstrap 1. 结构 先看一个这个类的类层次结构, ? 好,这个结构还是比较明晰的,然后看他的主要字段,因为这些字段比较重...

2595
来自专栏java一日一条

一个Java对象到底占用多大内存

大家可以用这个代码边看边验证,注意的是,运行这个程序需要通过javaagent注入Instrumentation,具体可以看原博客。我今天主要是总结下手动计算J...

361
来自专栏服务端技术杂谈

Java编码规范

命名 类名使用UpperCamelCase风格。 领域模型相关命名:DO / DTO / VO / DAO等。 方法名,参数名,成员变量,局部变量都统一使用lo...

2674
来自专栏码云1024

python简明笔记

通过 for 语句我们可以使用 for 循环。Python 里的 for 循环与 C 语言中的不同。这里的 for 循环遍历任何序列(比如列表和字符串)中的每一...

4948
来自专栏闻道于事

Java多线程详解

每个运行的程序就是一个进程,当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个进程。

673
来自专栏木木玲

Netty 源码解析 ——— ChannelConfig 和 Attribute

1262
来自专栏java一日一条

一个Java对象到底占用多大内存

大家可以用这个代码边看边验证,注意的是,运行这个程序需要通过javaagent注入Instrumentation,具体可以看原博客。我今天主要是总结下手动计算J...

321
来自专栏Java编程技术

诡异的类型转换

最近在做应用迁移时候遇到了一个诡异的类型转换问题,感觉比较有意思,就记录下来和大家分享下。

752
来自专栏Java 技术分享

两篇 Spring 总结(一)

983
来自专栏java一日一条

Java Socket 编程原理及教程

对于Java Socket编程而言,有两个概念,一个是ServerSocket,一个是Socket。服务端和客户端之间通过Socket建立连接,之后它们就可以进...

391

扫码关注云+社区