Java class 文件结构

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

一、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 回帖 • 1 关注

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 238 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 426 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖 • 1 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    476 引用 • 899 回帖 • 2 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    76 引用 • 421 回帖
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    5 引用 • 26 回帖 • 491 关注
  • 爬虫

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

    106 引用 • 275 回帖
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 692 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖 • 3 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 696 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 100 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    228 引用 • 1450 回帖
  • 程序员

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

    532 引用 • 3528 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 26 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    83 引用 • 165 回帖 • 43 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    19 引用 • 31 回帖 • 3 关注
  • CodeMirror
    1 引用 • 2 回帖 • 115 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6542 引用 • 29404 回帖 • 245 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 21 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 1 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 685 关注
  • Vim

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

    27 引用 • 66 回帖
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 60 回帖 • 467 关注