JAVA字节码文件之第一篇(结构)
程序员文章站
2022-06-23 22:32:24
魔数之后的四个字节是版本信息,前两个字节(00 00)是次版本号(minor version: 0),后两个字节(00 34)是主版本号(major version: 52),34是十六进制转换十进制为52;52对应的就是JDK1.8;所以该class文件的版本号=1.8.0;用过java -ver... ......
开发工具:ieda、jdk1.8、winhex
一、字节码文件结构
.class 字节码中有两种数据类型:
- 字节数据直接量:这是基本的数据类型。共细分为 u1 、 uz 、 u4 、 u8 四种,分别代表连续的 1 个字节、 2 个字节、 4 个字节、 8 个字节组成的整体数据。
- 表(数组):表是山多个基本数据或其他表,按照既定顺序组成的大的数据集合。表是有结构的,它的结构体现在:组成表的成分所在的位置和顺序都是已经严格定义好的。
class字节码文件的整体结构
二、demo分析
源代码:该代码贯穿整个字节码学习的章节
package com.jalja.java.bytecode; /** * @auther: xl * @date: 2020/1/4 12:58 * @description: */ public class bytecodetest { private int num=1; public int getnum() { return num; } public void setnum(int num) { this.num = num; } }
javap -verbose 分析一个字节码文件,会输出字节码文件的魔数、版本号、常量池、类信息、类的构造方法、类中方法的信息、类变量与成员变量等信息
f:\workspace\idea\study\jalja-base-utils\target\test-classes>javap -verbose com.jalja.java.bytecode.bytecodetest classfile /f:/workspace/idea/study/jalja-base-utils/target/test-classes/com/jalja/java/bytecode/bytecodetest.class last modified 2020-1-4; size 514 bytes md5 checksum b661c2792027e7c9169a0266523412c1 compiled from "bytecodetest.java" public class com.jalja.java.bytecode.bytecodetest minor version: 0 major version: 52 flags: acc_public, acc_super constant pool: #1 = methodref #4.#20 // java/lang/object."<init>":()v #2 = fieldref #3.#21 // com/jalja/java/bytecode/bytecodetest.num:i #3 = class #22 // com/jalja/java/bytecode/bytecodetest #4 = class #23 // java/lang/object #5 = utf8 num #6 = utf8 i #7 = utf8 <init> #8 = utf8 ()v #9 = utf8 code #10 = utf8 linenumbertable #11 = utf8 localvariabletable #12 = utf8 this #13 = utf8 lcom/jalja/java/bytecode/bytecodetest; #14 = utf8 getnum #15 = utf8 ()i #16 = utf8 setnum #17 = utf8 (i)v #18 = utf8 sourcefile #19 = utf8 bytecodetest.java #20 = nameandtype #7:#8 // "<init>":()v #21 = nameandtype #5:#6 // num:i #22 = utf8 com/jalja/java/bytecode/bytecodetest #23 = utf8 java/lang/object { public com.jalja.java.bytecode.bytecodetest(); descriptor: ()v flags: acc_public code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // method java/lang/object."<init>":()v 4: aload_0 5: iconst_1 6: putfield #2 // field num:i 9: return linenumbertable: line 8: 0 line 9: 4 localvariabletable: start length slot name signature 0 10 0 this lcom/jalja/java/bytecode/bytecodetest; public int getnum(); descriptor: ()i flags: acc_public code: stack=1, locals=1, args_size=1 0: aload_0 1: getfield #2 // field num:i 4: ireturn linenumbertable: line 12: 0 localvariabletable: start length slot name signature 0 5 0 this lcom/jalja/java/bytecode/bytecodetest; public void setnum(int); descriptor: (i)v flags: acc_public code: stack=2, locals=2, args_size=2 0: aload_0 1: iload_1 2: putfield #2 // field num:i 5: return linenumbertable: line 16: 0 line 17: 5 localvariabletable: start length slot name signature 0 6 0 this lcom/jalja/java/bytecode/bytecodetest; 0 6 1 num i } sourcefile: "bytecodetest.java"
winhex:打开class文件
二、魔数(magic number)
1、魔数 :所有的class字节码文件的前四个字节都是魔数,魔数是固定值0xcafebabe,jvm加载class时会验证该数据是否符合规范。
二、版本号(version)
2、版本号:
魔数之后的四个字节是版本信息,前两个字节(00 00)是次版本号(minor version: 0),后两个字节(00 34)是主版本号(major version: 52),34是十六进制转换十进制为52;52对应的就是jdk1.8;所以该class文件的版本号=1.8.0;用过java -version 可以验证。由于jvm是向下兼容,所以如何你的字节码文件版本号,小于等于当前jvm的版本,都是可以在当前jvm中运行的。
下一节:java字节码文件之常量池