Java Class类文件结构分析

Java的.Class类文件结构分析
序言:JVM 把我们的.java文件编译为.Class文件,本文只要分析
①反汇编Class文件后对应的java字节码指令
②Class文件的文件结构(使用工具WinHex查看)
第一步:
我们先写一个简单的.java程序(本文已Test02.java为例进行简单分析)
Test02.java代码如何:
Test02.java功能:求取自然数0-10的和并与10比较如果大于则返回和否则返回0
运行Test02.java后得到.class文件
.Class为java的字节码文件
第二步:
使用javap -c Test02.class>Test.txt命令把.class文件反汇编后的内容写入到Test.txt文件
在这里插入图片描述
接下来查看test.txt内容
在这里插入图片描述
**第三步:**分析对照java的原生程序分析java的字节码指令(把写的代码和字节码指令对照看看JVM的执行器是如何执行我们写的java代码)
``具体分析如图
在这里插入图片描述
具体代码如下:
①java文件代码

public class Test02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
			int m=test();
			System.out.println(m);
	}
	
	public static int test() {
		
		int m=0;
		for (int  i= 0;  i<=10; i++) {
			m=m+i;
		}
		
		if (m>10?true:false) {
			return m;
		}else {
			return 0;
		}
		
	}
}

②java字节码代码

Compiled from "Test02.java"
public class com.test.Test02 {
  public com.test.Test02();
    Code:
       0: aload_0							//第0项常量默认是空出来的
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V  在super的class文件中调用main方法
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #16                 //调用test方法
       3: istore_1							//把返回的值存入m的值送入栈
       4: getstatic     #20                 // 调用Java的打印输出流
       7: iload_1							//获得栈中的值(对应为main方法中m的值)
       8: invokevirtual #26                 //输出打印出来
      11: return

  public static int test();
    Code:
       0: iconst_0    //把0放入虚拟机栈栈顶
       1: istore_0	  //把栈顶0赋给变量m
       2: iconst_0	  //把0放入虚拟机栈栈顶
       3: istore_1	  //把栈顶0赋给变量i
       4: goto          14   	//此步开始for循环
       7: iload_0           	//把变量m的值放入虚拟机栈顶
       8: iload_1				//把变量i的值放入虚拟机栈顶
       9: iadd					//将栈顶的第一个值和第二个值相加得到结果存入栈顶
      10: istore_0				//把虚拟机栈顶的值付给第一个变量m(m的值为m+i的和)
      11: iinc          1, 1    //i自增
      14: iload_1           	//把m推送进虚拟机栈(m为0~10的和)
      15: bipush        10  	//把10推送进虚拟机栈
      17: if_icmple     7   	//比较虚拟机栈顶的两个int的大小,小于等于0跳转
      20: iload_0				//把m的值送入虚拟机栈顶
      21: bipush        10		//把10推送进虚拟机栈
      23: if_icmple     28		//比较虚拟机栈顶的两个int的大小,小于等于0跳转
      26: iload_0				//iload_0的值为所求的和
      27: ireturn				//返回和
      28: iconst_0				//iconst_0的值为0
      29: ireturn				//返回0
}

**第四步:我们将分析Class文件的结构(JVM是如何识别Class文件的)
**
.class是一个二进制的文件,二进制文件里并没有我们熟知的高级编程语言代码,所以接下来我们将走入计算机二进制的世界,Winhex将以16进制的形式展现出我们写的java程序经过编译后的Class文件,我们也主要分析Class (16进制)的结构 如图

在这里插入图片描述
如何去理解这一大推看不懂的十六进制数呢?这就需要理解Class的类文件结构
①Class的文件标识(标准叫法:魔数)
它是一个4字节数从文件开头算起0xCAFEBABE
在这里插入图片描述
②紧接着魔数后的4个字节为Class文件的版本号
在这里插入图片描述
③版本号过后就是常量池(Class文件结构中最复杂的部分)
前2个字节为常量池的数量

在这里插入图片描述
由上图可知值为0x28对应的十进制为40,常量池的数量=值-1,所以常量池数量为39
由此以后开始常量池的分析为了节约空间我直接给出常量池的截图,具体可以参考《深入理解JVM虚拟机》这本书
在这里插入图片描述
④接下来为访问标志(占2个字节)0x0021
在这里插入图片描述
⑤类索引,父类索引,接口索引集合
这三个各占2个字节
在这里插入图片描述
⑥字段表
在这里插入图片描述
⑦方法表
在这里插入图片描述
⑧属性表(方法表结束位2F以下 的内容为属性表内容)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值