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 the class file format; it has the value 0xCAFEBABE.

译: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 and major_version items are the minor and major version numbers of this class file. Together, a major and a minor version number determine the version of the class file format. If a class file has major version number M and minor version number m, we denote the version of its class 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.* support class file format versions in the range 45.0 through 45.65535 inclusive. For k ≥ 2, JDK release 1.k supports class 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包含了类文件在编译时所需要的各种常量,这些常量用于支持类的元数据、字段、方法、属性等的描述

未完待续...

posted @   勤匠  阅读(18)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示