class文件中,常量池之后的相关数据解析!【class二进制文件分析】

news/2024/11/23 20:48:26/

前言:前段时间读《深入java虚拟机》介绍到class文件的时候,由于理论知识较多,人总感觉疲惫不堪,就泛泛阅读了一下。在工作中使用起来知识点知道,但是总是需要查阅各种资料。今天有时间,继续整理常量池后面的相关知识。

文章目录

  • 1、访问标志
  • 2、类索引、父类索引、接口索引
  • 字段表集合
    • 1、字段表结构
    • 2、字段表的访问标识
  • 方法表集合
    • 1、方法表结构
    • 2、方法表的访问标识

  Last modified 2023-6-2; size 708 bytesMD5 checksum fc8bb4833223a10b68449d42080b1695Compiled from "Sample.java"
public class com.company.jvm.Sampleminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref          #6.#29         // java/lang/Object."<init>":()V#2 = Class              #30            // com/company/jvm/Sample#3 = Methodref          #2.#29         // com/company/jvm/Sample."<init>":()V#4 = String             #31            // 22#5 = Fieldref           #2.#32         // com/company/jvm/Sample.m1:Ljava/lang/String;#6 = Class              #33            // java/lang/Object#7 = Fieldref           #2.#34         // com/company/jvm/Sample.arr:[Ljava/lang/Object;#8 = Fieldref           #35.#36        // java/lang/System.out:Ljava/io/PrintStream;#9 = Methodref          #37.#38        // java/io/PrintStream.println:(Ljava/lang/String;)V#10 = Utf8               m1#11 = Utf8               Ljava/lang/String;#12 = Utf8               m2#13 = Utf8               arr#14 = Utf8               [Ljava/lang/Object;#15 = Utf8               <init>#16 = Utf8               ()V#17 = Utf8               Code#18 = Utf8               LineNumberTable#19 = Utf8               LocalVariableTable#20 = Utf8               this#21 = Utf8               Lcom/company/jvm/Sample;#22 = Utf8               main#23 = Utf8               ([Ljava/lang/String;)V#24 = Utf8               args#25 = Utf8               [Ljava/lang/String;#26 = Utf8               sample#27 = Utf8               SourceFile#28 = Utf8               Sample.java#29 = NameAndType        #15:#16        // "<init>":()V#30 = Utf8               com/company/jvm/Sample#31 = Utf8               22#32 = NameAndType        #10:#11        // m1:Ljava/lang/String;#33 = Utf8               java/lang/Object#34 = NameAndType        #13:#14        // arr:[Ljava/lang/Object;#35 = Class              #39            // java/lang/System#36 = NameAndType        #40:#41        // out:Ljava/io/PrintStream;#37 = Class              #42            // java/io/PrintStream#38 = NameAndType        #43:#44        // println:(Ljava/lang/String;)V#39 = Utf8               java/lang/System#40 = Utf8               out#41 = Utf8               Ljava/io/PrintStream;#42 = Utf8               java/io/PrintStream#43 = Utf8               println#44 = Utf8               (Ljava/lang/String;)V
{public java.lang.String m1;descriptor: Ljava/lang/String;flags: ACC_PUBLICpublic java.lang.String m2;descriptor: Ljava/lang/String;flags: ACC_PUBLICpublic java.lang.Object[] arr;descriptor: [Ljava/lang/Object;flags: ACC_PUBLICpublic com.company.jvm.Sample();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 3: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/company/jvm/Sample;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=2, args_size=10: new           #2                  // class com/company/jvm/Sample3: dup4: invokespecial #3                  // Method "<init>":()V7: astore_18: aload_19: ldc           #4                  // String 2211: putfield      #5                  // Field m1:Ljava/lang/String;14: aload_115: bipush        1217: anewarray     #6                  // class java/lang/Object20: putfield      #7                  // Field arr:[Ljava/lang/Object;23: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;26: aload_127: getfield      #5                  // Field m1:Ljava/lang/String;30: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V33: returnLineNumberTable:line 9: 0line 10: 8line 11: 14line 12: 23line 13: 33LocalVariableTable:Start  Length  Slot  Name   Signature0      34     0  args   [Ljava/lang/String;8      26     1 sample   Lcom/company/jvm/Sample;
}
SourceFile: "Sample.java"

1、访问标志

class文件中,我们可以通过背或记也好,或者通过查阅对照表。可以将常量池中的数据整理出来。常量池的数据,之后又是什么呢?紧接着的就是访问标志

标志名称标志值标志意义
ACC_PUBLIC0X0001是否为public类型
ACC_FINAL0X0010是否被声明为final,只有类可设置
ACC_SUPER0x0020在jdk1.0.2之后编译出来的类的这个标志都为真
ACC_INTERFACE0x0200标识是一个接口
ACC_ABSTRACT0x4000是否为abstract类型,如为真,其他类型均为假,如INTERFACE
ACC_SYNTHETIC0x1000标识这个类并非由用户产生
ACC_ANNOTATION0x2000标识这是一个注解
ACC_ENUM0x4000标识这是一个枚举
ACC_MODULE0x8000标识这是一个模块

这里先上一张二进制的图:
在这里插入图片描述

下面是常量池之后的class文件截取的部分:

00 21 

访问标志,占用空间:U2,这里占用了十六进制的4个位,则是0x0021。这里我啰嗦一下,一个字节为8个位,对应到十六机制来说【两个位】代表一个字节。eg:0xF标识二进制的0000 1111,去除高位的0,就是1111。
在表格中我们说过,ACC_SUPER标志在jdk1.0.2之后的版本其值都为真,则是0x0020,说明其访问标志ACC_PUBLIC为真!0x0001|0x0020=0x0021

2、类索引、父类索引、接口索引

访问标志结束之后,就来到了我们所声明的类例,如下伪代码

public class dog extend cat implement animal{}
00 02 00 06 00 00

__类索引、父类索引、接口索引占用的内存均为u2。

u2索引说明
00 02#2代表当前类的索引,通过查找为com/company/jvm/Sample
00 08#8代表当前父类索引,通过查找为Object
00 000代表当前文件没有接口

字段表集合

通过字面意,就能得知这里将要介绍的是类或接口成员字段

//这里写个伪代码
public final static int AGE=10;

1、字段表结构

类型名称数量说明
u2filed_count1字段数量
u2access_flag1访问标志
u2name_index1名称索引
u2descriptor_index1类型索引
u2attribute_count1属性计数器
u2attributesattribute_count属性值集合

2、字段表的访问标识

标志名称标志值含义
ACC_PUBLIC0x0001字段是否为公开
ACC_PRIVATE0x0002字段是否为私有
ACC_PROTECTED0x0004字段是否为保护
ACC_STATIC0x0008字段是否为静态
ACC_FINAL0x0010字段是否为Final
ACC_VOLATILE0x0040字段是否在并发时可见
ACC_TRANSIENT0x0080字段是否序列化
ACC_SYNTHETIC0x1000字段是否由编译器自己决定
ACC_ENUM0x4000字段是否为枚举
00 03 00 01 00 0a 00 0b  00 00 00 01 00 0c 00 0b 00 00 00 01 00 0d 00 0e 00 00 
位值说明
第一个成员字段
00 03代表字段数量有3个
00 01代表字段访问标志位public
00 0a代表名称索引为10 名称为 m1
00 0b代表descriptor的索引值为11 对象类型为Ljava/lang/String;【分号;全限定名】
00 00代表没有属性数量
第二个成员字段
00 01代表字段访问标志位为public
00 0c代表字段名称索引为12,名称为m2
00 0b代表类型的索引11,类型为 Ljava/lang/String;同上
00 00代表没有属性
第三个成员字段
00 01同上
00 0d名称索引为13,经查找为arr
00 0e类型索引为14,经查找为 [Ljava/lang/Object;全限定名,其中“[”代表为数组
00 00代表没有属性,数量为0

方法表集合

唠嗑时间开始,写到这里花了三个多小时。从排版到书写上面确实有很大的提升。此时的我确实有点疲惫。仔细一想,没啥子疲惫不疲惫的,路虽远,但始终在路上,总会到达终点。突然想到书上说过这样的一句:当你在解决一个问题的时候,你会感到很疲惫,这时候千万别放弃。因为大部分的人就此放弃了,而你还在路上行走。当你解决之后,你又比别人强了不少!

写到这里【字段表集合】之后,这里就会很轻松。这里再啰嗦一下,字段表分为:成员字段数量、字段名索引、字段类型索引、字段属性数量、字段属性集合。

1、方法表结构

类型名称数量说明
method_count方法数量
u2access_flag1访问标志
u2name_index1名称索引
u2descriptor_index1类型索引
u2attribute_count1属性计数器
u2attributesattribute_count属性值集合
~~~~

2、方法表的访问标识

标志名称标志值含义
ACC_PUBLIC0x0001方法是否为公开
ACC_PRIVATE0x0002方法是否为私有
ACC_PROTECTED0x0004方法是否为保护
ACC_STATIC0x0008方法是否为静态
ACC_FINAL0x0010方法是否为Final
ACC_SYNCHRONIZED0x0020方法是否在并发时可见
ACC_BRIDGE0x0040方法是不是由编译器产生的桥接方法
ACC_VARCHAR0x0080方法是否接收不可定参数
ACC_NATIVE0x0100方法是否为Native
ACC_ABSTRACT0x0400方法是否为abstract
ACC_STRICT0x0800方法是否为strictfp【修饰在接口和类,对精确率类型较高且跨平台的计算结果要求比较严格的清醒的话,建议使用该strictfp关键词。】
ACC_SYNTHETIC0x1000方法是否由编译器自动产生

继续上方发表的字节码:

00 02 00 01 00 0f 00 10 00 01 00 11 00 00 00 2f 00 01 00 01 00 00  
位码说明
00 02方法数量为2
00 01方法访问标识为0x0001,经查为public
00 0f方法名索引为15,经查为
00 10方法类型索引16,经查为()V
00 01说明属性表集合有1项属性
00 11属性名称的索引值为17,对应的为Code
~~未完待续

http://www.ppmy.cn/news/172722.html

相关文章

解决联想电脑“未安装音频设备”问题

电脑&#xff1a;联想昭阳E47 操作系统&#xff1a;win7&#xff0c;32位 问题&#xff1a;扬声器正常&#xff0c;内置麦克风使用不了&#xff0c;点击“控制面板”-“声音”-“录音设备”&#xff0c;显示“未安装音频设备” 解决方法&#xff1a; 判断是声卡驱动没有更新。 …

联想笔记本win10突然没有显示网络?找不到Wlan,适配器驱动程序的问题

解决办法简介&#xff1a; 此电脑——右键属性——设备管理器——找到网络适配器中带wireless的适配器——右键禁用、再启用——如果没有效果&#xff0c;就再右键更新驱动程序就可以了。 问题描述图片&#xff1a; 解决办法截图&#xff1a; 此电脑——右键属性——设备管理…

联想e470加装固态硬盘_联想e470能不能加固态硬盘?

1.首先要先断开内置电池连接线&#xff1a; 2.拆开支架&#xff0c;进而取下硬盘&#xff0c;然后断开硬盘排线&#xff0c;进而取下硬盘支架&#xff1a; 3.这个方法的前提就是本本在买来的时候就有额外的预留接口&#xff0c;那么就可根据预留接口的型号来购买相应的SSD直接安…

联想电脑黑屏但电源键亮着的解决办法

最近有联想电脑用户跟小编反应&#xff0c;自己的笔记本屏幕黑屏了但是电源键还是亮着的&#xff0c;这是怎么回事&#xff1f;很多用户遇到这种情况往往不知所措&#xff0c;不知道如何处理&#xff0c;那么小编这里就给大家分享一下联想电脑黑屏电源键亮着的解决办法。 方法一…

BUUCTF Misc Page2-6部分题目

Page 2 1.被劫持的神秘礼物-流量分析、字符查找 打开后文件有2种数据流&#xff0c;HTTP和TCP&#xff0c;两个都追踪一下 这是TCP,好像没什么东西 再看看HTTP流&#xff1b;查看密码既可以随便打开一个HTTP流&#xff0c;也可以整个追踪&#xff0c; 得到用户名和密码&#x…

php sphinx应用场景,Sphinx+Scws 搭建千万级准实时搜索应用场景详解

目标&#xff1a; 一、搭建准确的千万级数据库的准实时搜索(见详情) 二、实现词语高亮(客户端JS渲染&#xff0c;服务器端渲染&#xff0c;详见7.3) 三、实现搜索联想(输入框onchange,ajax请求搜索&#xff0c;取10条在层上展示方可) 四、实现词库管理(仅需管理scws下的自定义词…

安装虚拟机,”intel vt-x 处于禁用状态“ 如何开启

一、出现的问题 在VMware首页中打开虚拟机&#xff0c;报错&#xff0c;出现下面的错误&#xff1a; 原因&#xff1a;BIOS权限的Inter 虚拟机技术默认为disabled&#xff0c;需要修改为enable。 二、进入BIOS快捷键 不同的机子BIOS设置不一样&#xff0c;进入BIOS的按键有差…

昭阳E47A每天第一次开机启动速度慢的原因

摘自&#xff1a;昭阳E47 A每天第一次运行速度慢的原因 自己的电脑症状描述&#xff1a;电脑每天第一次开机启动速度都很慢&#xff0c;再关机重启问题不再出现&#xff0c;经百度找到如下答案&#xff0c;经实践问题解决&#xff0c;故把收集的资料整理于此&#xff0c;给遇到…