一、 java class 字节码概述以及Java字节码结构

本文介绍了Java类的字节码文件结构及解析过程,包括魔数、版本号、常量池等10个组成部分,并解释了它们的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java类型识别:Java类是编译器生成字节码有其特定的组织规律,Java虚拟机在加载类时,对编译期生成的字节码信息按照固定的格式进行解析,一步一步解析出来字节码中所存在的类型结构信息,从而在运行期完全还原出原始的Java类的全部结构  。

class的字节概述:每一个Java类被编译之后生成一个对应的.class 字节码文件,需要明白jvm加载java类的原理,首先需要知道java类被编译之成的.class格式文件结构。下面通过实例代码来描述字节码的组成格式。

 

一、idea中实例查看

1、首先我们在ida中创建一个项目,demo,然后  编译一下,如下图所示:

以上文件就是一个spring boot 项目的一个程序入口带有main 方法的类

2、查看编译之后的字节码文件:通过在ida中安装HexView插件查看(HexView使用,请翻看另一篇安装HexView),

3、通过反编译之后的class文件,做如下对比:

通过以上两个文件前后对比,我们发现编译后的文件,自动加上了默认的构造该函数 

二、class 文件构成基础

1、class文件构成基础

在class字节码文件中,数据都是以二进制流的形式存储。字节流都安装规定的顺序排序,字节码之间不存在任何空袭,对于超过8位的数据,按照Big-Endian(大端)的顺序存储,即:低地址存放高有效字节,反之小端(little endian):低字节存放地有效字节

2、class 文件的10个组成结构

  class字节码文件采用类似c语言的结构体存储数据,主要分以下

(1),我们来说明一下:class文件只有两种数据类型:无符号数。如下表所示

数据类型定义说明
无符号无符号数可以用来描述数字、索引引用、数量值或按照utf-8编码构成的字符串值。其中无符号数属于基本的数据类型。
以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节
表是由多个无符号数或其他表构成的复合数据结构。有的表都以“_info”结尾。
由于表没有固定长度,所以通常会在其前面加上个数说明。

(2)、以下就是字节码结构表

类型名称说明长度(字节)
u4magic魔数,识别Class文件格式4
u2minor_version副版本号2
u2major_version主版本号2
u2constant_pool_count常量池计算器2
cp_infoconstant_pool常量池n
u2access_flags访问标志2
u2this_class类索引2
u2super_class父类索引2
u2interfaces_count接口计数器2
u2interfaces接口索引集合2
u2fields_count字段个数2
field_infofields字段集合n
u2methods_count方法计数器2
method_infomethods方法集合n
u2attributes_count附加属性计数器2
attribute_infoattributes附加属性集合n

 

一个class字节码文件主要由以下10部分组成:

1、MaginNamber

2、Version

3、Constant_pool

4、Access_flag

5、This_class

6、Super_class

7、Interfaces

8、Fields

9、Methods

10、Attributes

三、二进制文件解读,如下图所示:

1、MaginNamber 即魔数,是用来标志class文件的,位于每一个java class 文件的最前面4个字节,值固定为0xCAFEBABE不变。虚拟机加载文件时会先检查这4个字节,如果不是0xCAFEBABE,则虚拟机拒绝加载该文件,这样就可以防止加载非class文件而造成虚拟机奔溃。

2、Version 即版本号,字段由2个长度为2个字节的字段组成,分别是Major Version 和 Minor Version,代表当前class文件的主版本号和次版本号 。不同的虚拟机支持Java class 文件的版本范围是不同的,所以在加载class文件之前可以先看看该class文件是否为当前虚拟机支持范围之内的,避免加载不支持的class文件。(高版本兼容低版本,反转不支持)

3、Constant_pool 即常量池,是从class文件的第9个字节开始。首先是2个字节(第9、第10两个字节)的长度字段constant_pool_count,表名常量池包含了多少个常量。接下来是二进制信息描述[constant_pool_conut-1]个常量,里面放的是字面常量和符号引用。

  字面常量主要包含文本串以及被声明final的常量。

  符号引用包含类和接口的全局限定名、字段的名称和描述符、方法的名称和描述符。

4、Access_flag,主要保存当前类的访问权限。

5、This_cass,主要保存当前类的全局限定名在常量池的索引。

6、Super_class,主要保存当前类的父类的全局限定名在常量池里的索引。

7、Interfaces,主要保存当前类的接口列表,包含两部分内容:interfaces_count和interfaces[interfaces_count]

interfaces_count指的是当前类实现的接口数目。

interfaces[]是包含interfaces_count 个接口的全部限定名的索引的数组。

8、Fields,主要保存当前类的成员列表,包含两部分内容:fields_count 和 fields[fields_count ].

fields_count 是类变量和实例变量字段的数量总和。

field[]是包含字段详细信息列表。

9、Methods,主要保存当前类的方法列表,包含两部分内容:Methods_count 和 Methods[Methods_count].

Methods_count是该类或者接口显式定义的方法的数量。

Methods[]是包含方法信息的一个详细列表。

10、Attributes,主要保存当前类attribute列表,包含Attributes_count 和Attributes[Attributes_count].

好了,暂时就先学习到这吧,眼睛都看晕了

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值