JVM——.class详解
上一篇畅聊了Java,这篇解释.class文件。我们依然以Hello.java
为例。
public class Hello {
public static String app_name = "test";
public static void main(String[] args) {
Integer value = 10;
for (Integer i = 0; i < value;i++){
System.out.println(app_name);
}
}
}
用javac Hello.java
编译Java文件,得到一个.class
文件,打开Hello.class
文件
idea原是不能以16进制打开
.class
文件,你需要下插件BinEd - Binary/Hexadecimal Editor
,然后右击.class
文件,"Open In"->"Binary Editor(BinEd Plugin)",就可以打开
看看Hello.class
的内容
CA FE BA BE
00 00
00 34
00 36
0A 00
09 00
1F 0A
00 20
00 21 0A 00 20 00 22 09 00 23 00 24 09 00 08 00 25 0A 00 26 00 27 08 00 28 07 00 29 ...
一大串的16进制数字简直把人都要看疯啦,建议多看几个.class
文件,你会发现一个共同点:所有.class
文件的起始永远是CA FE BA BE,那么这个CA FE BA BE到底是什么意思呢?我们不妨去oracle官网找找答案(Chapter 4. The class File Format (oracle.com)),官网中有这么一段代码
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
u4 magic;
u4代表8个16进制位,也就是CA FE BA BE 所占的位置,这是啥意思呢?接着官网往下看
magic
The
magic
item supplies the magic number identifying theclass
file format; it has the value0xCAFEBABE
.译:magic
magic项提供标识类文件格式的magic数;它的值为0xCAFEBABE。
也就是说CA FE BA BE标识.class文件的标准,有点像xml文件中第一行 <?xml version="1.0">,这里我们就将它理解成是.class文件的标准,JVM以文件是否以0xCAFEBABE开头识别此文件是否是一个.class文件。
第2和第3行(u2 minor_version;u2 major_version;)
minor_version, major_version
The values of the
minor_version
andmajor_version
items are the minor and major version numbers of thisclass
file. Together, a major and a minor version number determine the version of theclass
file format. If aclass
file has major version number M and minor version number m, we denote the version of itsclass
file format as M.m. Thus,class
file format versions may be ordered lexicographically, for example, 1.5 < 2.0 < 2.1.A Java Virtual Machine implementation can support a
class
file format of version v if and only if v lies in some contiguous range Mi.0 ≤ v ≤ Mj.m. The release level of the Java SE platform to which a Java Virtual Machine implementation conforms is responsible for determining the range.Oracle's Java Virtual Machine implementation in JDK release 1.0.2 supports
class
file format versions 45.0 through 45.3 inclusive. JDK releases 1.1.* supportclass
file format versions in the range 45.0 through 45.65535 inclusive. For k ≥ 2, JDK release 1.k supportsclass
file format versions in the range 45.0 through 44+k.0 inclusive.译:minor_version, major_version
minor_version和major_version项的值是这个类文件的次要和主要版本号。主版本号和次版本号一起决定了类文件格式的版本。如果一个类文件的主要版本号为M,次要版本号为m,我们将其类文件格式的版本记为M. m。因此,类文件格式的版本可以按字典顺序排列,例如,1.5 < 2.0 < 2.1。Java虚拟机实现可以支持版本v的类文件格式,当且仅当v位于某个连续范围Mi.0≤v≤Mj.m。Java虚拟机实现所遵循的Java SE平台的发布级别负责确定范围。
Oracle在JDK 1.0.2版中的Java虚拟机实现支持45.0到45.3(含45.3)版本的类文件格式。JDK版本1.1。*支持45.0到45.65535的类文件格式版本。当k≥2时,使用JDK版本1。K支持45.0到44+ K的类文件格式版本。0包容性。
第二第三行标记的是
.class
文件的版本,0x34=52,52对应 JDK1.8参考此表
jdk版本号 class版本号 16进制值 1.1 45 00 00 00 2D 1.2 46 00 00 00 2E 1.3 47 00 00 00 2F 1.4 48 00 00 00 30 1.5 49 00 00 00 31 1.6 50 00 00 00 32 1.7 51 00 00 00 33 1.8 52 00 00 00 34
u2 constant_pool_count;
The value of the constant_pool_count item is equal to the number of entries in the constant_pool table plus one. A constant_pool index is considered valid if it is greater than zero and less than constant_pool_count, with the exception for constants of type long and double noted in §4.4.5.
译:constant_pool_count项的值等于constant_pool表中的条目数加1。如果一个常量大于0且小于constant_pool_count则被认为是有效的,但§4.4.5中提到的long和double类型的常量除外。
常量池中项的数量,比如我们定义的static int,static function。不过奇怪的是我就定义了一个常量,为何值为0x36?这是因为
constant_pool_count
的值并不是直接由源代码中定义的常量的数量决定的。实际上,constant_pool
包含了类文件在编译时所需要的各种常量,这些常量用于支持类的元数据、字段、方法、属性等的描述
未完待续...
本文来自博客园,作者:勤匠,转载请注明原文链接:https://www.cnblogs.com/JarryShu/articles/18159004
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现