Java class 文件结构

本贴最后更新于 2881 天前,其中的信息可能已经天翻地覆

一、class 文件数据项的类型
u1
u2
u4
u8
...

二、class 文件的数据项

类型 名称 数量
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 attribute_count 1
attribute_info attributes attributes_count

三、各数据项
1、魔数(magic)
4 个字节,固定为 0XCAFEBABE。

2、次版本号(minor_version)
2 个字节。

3、主版本号(major_version)
2 个字节。

4、常量池大小(constant_pool_count)
2 个字节。

5、常量池(constant_pool)
constant_pool_count-1 个 cp_info。
索引为 0 的常量池项空白,引用索引为 0 的常量池项则表示不引用任何常量池项。
常量池数据项类型:

常量池中数据项类型 类型标志 类型描述
CONSTANT_Utf8 1 UTF-8 编码的 Unicode 字符串
CONSTANT_Integer 3 int 类型字面值
CONSTANT_Float 4 float 类型字面值
CONSTANT_Long 5 long 类型字面值
CONSTANT_Double 6 double 类型字面值
CONSTANT_Class 7 对一个类或接口的符号引用
CONSTANT_String 8 String 类型字面值
CONSTANT_Fieldref 9 对一个字段的符号引用
CONSTANT_Methodref 10 对一个类中声明的方法的符号引用
CONSTANT_InterfaceMethodref 11 对一个接口中声明的方法的符号引用
CONSTANT_NameAndType 12 对一个字段或方法的部分符号引用

class 文件的特殊字符串:
i. 类的全限定名:java/lang/Object
ii. 描述符:

基本数据类型和 void 类型 类型的对应字符
byte B
char C
double D
float F
int I
long J
short S
boolean Z
void V

引用类型:“L”+ 类型的全限定名 +“;”
数组类型:若干个“[”+ 数组中元素类型的对应字符串
方法:(参数 1 类型 参数 2 类型 参数 3 类型 ...)返回值类型 //各个参数类型之间没有空格, 参数列表和返回值类型之间也没有空格

iii. 特殊方法的方法名
构造方法:<init>
静态代码块:<clinit>

  • CONSTANT_Utf8
一个 CONSTANT_Utf8_info
tag(1 个字节)
length(2 个字节)
bytes(length 个字节)

CONSTANT_Utf8 类型数据项可表示:程序中的字符串常量, 类型的全限定名, 方法和字段的名称, 方法和字段的描述符, 属性相关字符串。

  • CONSTANT_NameAndType
一个 CONSTANT_NameAndType_info
tag(1 个字节)
name_index(名称)
descriptor_index(描述符)

一个 CONSTANT_NameAndType_info 就表示了一个被调用的方法(如父类的构造函数)或一个被使用的字段。
仅在类中定义的字段或方法没有相应的 CONSTANT_NameAndType_info。

  • CONSTANT_Integer
一个 CONSTANT_Integer_info
tag(1 个字节)
bytes(4 个字节)
  • CONSTANT_Float
一个 CONSTANT_Float_info
tag(1 个字节)
bytes(4 个字节)
  • CONSTANT_Long
一个 CONSTANT_Long_info
tag(1 个字节)
bytes(8 个字节)
  • CONSTANT_Double
一个 CONSTANT_Double_info
tag(1 个字节)
bytes(8 个字节)
  • CONSTANT_String
一个 CONSTANT_String_info
tag(1 个字节)
string_index(2 个字节)
  • CONSTANT_Class
    一个 CONSTANT_Class_info 是对类或者接口的符号引用(包括数组)。
一个 CONSTANT_Class_info
tag(1 个字节)
name_index(类的全限定名,2 个字节)
  • CONSTANT_Fieldref
    该数据项表示对一个字段的符号引用, 可以是对本类中的字段的符号引用, 也可以是对其他类中的字段的符号引用, 可以是对成员变量字段的符号引用, 也可以是对静态变量的符号引用。
    字段必须被使用才会有相应的符号引用,只在类中定义是没有符号引用的。
一个 CONSTANT_Fieldref_info
tag(1 个字节)
class_index(2 个字节)
name_and_type_index(2 个字节)
  • CONSTANT_Methodref
    对一个类中方法的符号引用, 可以是对本类中的方法的符号引用, 也可以是对其他类中的方法的符号引用, 可以是对成员方法的符号引用, 也可以是对静态方法的符号引用,但是不会是对接口中的方法的符号引用。
    方法必须被调用才会有相应的符号引用,只在类中定义是没有符号引用的。
一个 CONSTANT_Methodref_info
tag(1 个字节)
class_index(2 个字节)
name_and_type_index(2 个字节)
  • CONSTANT_InterfaceMethodref
    表示对一个接口方法的符号引用。
一个 CONSTANT_InterfaceMethodref_info
tag(1 个字节)
class_index(2 个字节)
name_and_type_index(2 个字节)

6、当前类(或者接口)的访问修饰符(access_flags)
2 个字节

志名 标志值 标志含义 针对的对像
ACC_PUBLIC 0x0001 public 类型 所有类型
ACC_FINAL 0x0010 final 类型
ACC_SUPER 0x0020 使用新的 invokespecial 语义 类和接口
ACC_INTERFACE 0x0200 接口类型 接口
ACC_ABSTRACT 0x0400 抽象类型 类和接口
ACC_SYNTHETIC 0x1000 该类不由用户代码生成 所有类型
ACC_ANNOTATION 0x2000 注解类型 注解
ACC_ENUM 0x4000 枚举类型 枚举

7、对当前类的描述(this_class)(类的全限定名)
2 个字节(对一个 CONSTANT_Class_info 数据项的索引)。

8、对当前类的超类的描述(super_class)
2 个字节(对一个 CONSTANT_Class_info 数据项的索引)。

9、当前类所实现的接口的数量(interfaces_count)
注意, 只有当前类直接实现的接口才会被统计, 如果当前类继承了另一个类, 而另一个类又实现了一个接口, 那么这个接口不会统计在当前类的 interfaces_count 中。

10、当前类所实现的接口(interfaces)
interfaces_count 个 u2。
每个数据项指向常量池中的一个 CONSTANT_Class_info。

11、当前的类中定义的字段的个数(fields_count)
2 个字节。
注意, 这里包括静态字段, 但不包括从父类继承的字段。 如果当前 class 文件是由一个接口生成的, 那么这里的 fields_count 描述的是接口中定义的字段, 我们知道, 接口中定义的字段默认都是静态的。此外要说明的是, 编译器可能会自动生成字段, 也就是说, class 文件中的字段的数量可能多于源文件中定义的字段的数量。 举例来说, 编译器会为内部类增加一个字段, 这个字段是指向外围类的对象的引用。

12、当前的类中定义的字段(fields)
field_count 个 field_info。
field 结构:

一个 field
access_flags
name_index
descriptor_index
attributes_count
attributes
  • 标志位(access_flags)
    2 个字节。
标志位名称 含义 设定者
ACC_PUBLIC 0x0001 字段被设为 public 类和接口
ACC_PRIVATE 0x0002 字段被设为 private
ACC_PROTECTED 0x0004 字段被设为 protected
ACC_STATIC 0x0008 字段被设为 static 类和接口
ACC_FINAL 0x0010 字段被设为 final 类和接口
ACC_VOLATILE 0x0040 字段被设为 volatile
ACC_TRANSIENT 0x0080 字段被设为 transient
  • 字段名(name_index)
    2 个字节。
    指向常量池中的一个 CONSTANT_Utf8_info 数据项。

  • 描述符(descriptor_index)
    2 个字节。
    指向常量池中的一个 CONSTANT_Utf8_info 数据项。

  • 属性数量(attributes_count)
    2 个字节。

  • 属性(attributes)
    可以出现在 filed_info 中的属性有三种, 分别是 ConstantValueDeprecated, 和 Synthetic

13、当前的类中定义的方法的个数(methods_count)

标志位名称 标志值 设定含义 设定者
ACC_PUBLIC 0x0001 方法设为 public 类和接口
ACC_PRIVATE 0x0002 方法设为 private
ACC_PROTECTED 0x0004 方法设为 protected
ACC_STATIC 0x0008 方法设为 static
ACC_FINAL 0x0010 方法设为 final
ACC_SYNCHRONIZED 0x0020 方法设为 sychronized
ACC_NATIVE 0x0100 方法设为 native
ACC_ABSTRACT 0x0400 方法设为 abstract 类和接口
ACC_STRICT 0x0800 方法设为 strictFP 类和接口的方法

可以出现在 method_info 中的属性分别是 CodeDeprecatedExceptions Synthetic

14、attribute_count

15、attribute
SourceFile // 内部类的,描述其外部类
InnerClasses // 外部类的,描述其内部类
Synchetic // 表示不是由用户代码生成的,是由编译器自动添加的,可以修饰方法和字段,例如,如果一个类不定义构造方法, 那么编译器会自动添加一个无参数的构造方法, 如果定义了静态字段或静态代码块, 还会根据具体情况, 增加静态初始化方法
ConstantValue // 修饰字段
Deprecated // 修饰字段和方法

符号引用

最基本的 UTF-8 编码的 Unicode 字符串
CONSTANT_Utf8

字面量
CONSTATN_Integer
CONSTATN_Long
CONSTATN_Float
CONSTANT_Double
CONSTANT_String

符号引用
CONSTANT_Class // 类或接口的符号引用
CONSTATN_NameAndType // 一个字段或方法的部分符号引用
// 以下三种符号引用由上面两种符号引用组成
CONSTATN_Fieldref // 字段的符号引用
CONSTANT_Methodref // 类中声明的方法的符号引用
CONSTANT_InterfaceMethodref // 接口中声明的方法的符号引用

#1、#2 等表示在常量池中的下标
#0 表示不引用任何常量池的项,比如

直接引用
就是偏移量,根据这些偏移量可以找到相应的类,并在类的内存区域中找到对应的字段或方法。

class 文件其实就存了两样东西:字面量符号引用

参考:
《深入理解 Java 虚拟机》
《Java 虚拟机规范(JavaSE8)》
http://blog.csdn.net/brave2211/article/category/1593711/1

  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 4 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    4 引用 • 16 回帖 • 201 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 691 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 113 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖 • 1 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    201 引用 • 120 回帖
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖 • 1 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 59 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 26 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖 • 4 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    168 引用 • 598 回帖 • 2 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 6 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 661 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 720 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    16 引用 • 143 回帖 • 3 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 119 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 158 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    594 引用 • 3541 回帖 • 1 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 1 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 8 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 23 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 63 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖 • 2 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 762 关注