Java字节码解析

最近在学Jvm相关的知识,看完视频,找了点字节码的资料看,理解字节码的含义。推荐 一文让你明白Java字节码

示例代码

从一个简单类 Math.java 开始:

public class Math {

    private int m;

    public int inc() {
        return m + 1;
    }
}

javac Math.java 得到字节码文件 Math.class,文件内容:

cafe babe 0000 0034 0013 0a00 0400 0f09
0003 0010 0700 1107 0012 0100 016d 0100
0149 0100 063c 696e 6974 3e01 0003 2829
5601 0004 436f 6465 0100 0f4c 696e 654e
756d 6265 7254 6162 6c65 0100 0369 6e63
0100 0328 2949 0100 0a53 6f75 7263 6546
696c 6501 0009 4d61 7468 2e6a 6176 610c
0007 0008 0c00 0500 0601 0004 4d61 7468
0100 106a 6176 612f 6c61 6e67 2f4f 626a
6563 7400 2100 0300 0400 0000 0100 0200
0500 0600 0000 0200 0100 0700 0800 0100
0900 0000 1d00 0100 0100 0000 052a b700
01b1 0000 0001 000a 0000 0006 0001 0000
0001 0001 000b 000c 0001 0009 0000 001f
0002 0001 0000 0007 2ab4 0002 0460 ac00
0000 0100 0a00 0000 0600 0100 0000 0600
0100 0d00 0000 0200 0e

内容解读

参照图例:

魔数

cafe babe:魔数,文件后缀标识,被java虚拟机接受。

版本号

0000:次版本号

0034:主版本号=52,java 1.8

常量池

0013:常量池入口,2+n,十进制=19,表明有18个常量,从1开始

0a:十进制=10,对应CONSTANT_Methodref_info,指向声明方法

0004:常量索引#4

000f:常量索引#15

09:十进制=9,对应CONSTANT_Fieldref_info,指向字段的类或接口描述

0003:常量索引#3

0010:常量索引#16

07:十进制=7,对应CONSTANT_Class_info,指向全限定名常量项的索引

0011:常量索引#17

07:同上

0012:常量索引#18

01:十进制=1,对应表中的CONSTANT_Utf8_info,utf8编码的字符串长度

0001:字符串长度为1

6d:109=”m”

01:同上

0001:同上

49:49=”1”

01:同上

0006:同上

3c 696e 6974 3e:字符串=

01:同上

0003:同上

2829 56:()V

01:同上

0004:同上

436f 6465:C_de

01:同上

000f:同上

4c 696e 654e 756d 6265 7254 6162 6c65:LineNumberTable

01:同上

0003:同上

69 6e63:inc

01:同上

0003:同上

28 2949:()I

01:同上

000a:长度为10的字符串

53 6f75 7263 6546 696c 65:SourceFile

01:同上

0009:同上

4d61 7468 2e6a 6176 61:Math.java

0c:十进制=12,CONSTANT_NameAndType_info,指向该字段或方法名称常量项的索引

0007:字段或者名字名称常量项索引#7

0008:字段或者名字名称常量项索引#8

0c:同上

0005:字段或者名字名称常量项索引#5

0006:字段或者名字名称常量项索引#6

01:同上

0004:同上

4d61 7468:Math

01:同上

0010:同上

6a 6176 612f 6c61 6e67 2f4f 626a 6563 74:java/lang/Object

==== 常量解析完毕,共18个常量

Access_Flag 访问标志部分

0x0021:是 0x0020 和 0x0001 的并集。

0021:ACC_PUBLIC,访问修饰符为Public。

类索引

类索引用于确定类的全限定名。

0003:引用第3个常量,第3个常量引用第17个常量,为 Math。

父类索引

0004:引用第18个常量,为 java/lang/Object。

接口索引

0000:没有接口。

字段表集合

字段表用于描述类和接口中声明的变量。这里的字段包含了类级别变量以及实例变量,但是不包括方法内部声明的局部变量。

0001:字段属性。

0002:Private访问。

0005:常量索引#5,为”m”。

0006:常量索引#6,为”1”。

0000:属性表数量为0。

方法

to be continued…