前言
分析之前的说明:
1、一位十六进制的数等于四位二进制的数。一个字节等于8位二进制数,2位16进制为一个字节。
2、这张图是一张java字节码的总览图,我们也就是按照上面的顺序来对字节码进行解读的。一共含有10部分,包含魔数,版本号,常量池等等,接下来我们按照顺序一步一步解读。
3、了解一下常量池的项目类型表
4、ASCII
附虚拟机指令集:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.putfield
开始
1、首先上一个测试的java代码。
package com.demo;
public class Demo {
private int a = 1;
protected void testMethod() {
}
}
2、然后执行编译命令:javac Demo.java,编译成Demo.class。
用sublime Text打开class文件,可以看到这样的16进制文件
cafe babe 0000 0034 0012 0a00 0400 0e09
0003 000f 0700 1007 0011 0100 0161 0100
0149 0100 063c 696e 6974 3e01 0003 2829
5601 0004 436f 6465 0100 0f4c 696e 654e
756d 6265 7254 6162 6c65 0100 0a74 6573
744d 6574 686f 6401 000a 536f 7572 6365
4669 6c65 0100 0944 656d 6f2e 6a61 7661
0c00 0700 080c 0005 0006 0100 0d63 6f6d
2f64 656d 6f2f 4465 6d6f 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 2600
0200 0100 0000 0a2a b700 012a 04b5 0002
b100 0000 0100 0a00 0000 0a00 0200 0000
0300 0400 0400 0400 0b00 0800 0100 0900
0000 1900 0000 0100 0000 01b1 0000 0001
000a 0000 0006 0001 0000 0008 0001 000c
0000 0002 000d
3、根据前言2的图表逐个分析。
分析如下,后面还有部分未分析,可参考链接https://www.jianshu.com/p/252f381a6bc4
//一位十六进制的数等于四位二进制的数。一个字节等于8位二进制数,
//一个字节等于2位16进制
cafe babe //魔数,CAFE BABE = 咖啡
0000 0034 //次版本号:0,主版本号:52
--------------------------常量池开始-------------------------
0012 //常量池数量18-1
0a //methodref_info,第1个
0004 000e //索引项#4,索引项#14
09 //fieldref_info,第2个
0003 000f //#3,#15
07 //class_info,第3个
0010 //#16
07 //class_info, 第4个
0011 //#17
01 //utf8_info, 第5个
0001 //长度1个字节
61 // 值:a
01 //utf8_info,第6个
0001 //长度1
49 // 值:I
01 //utf8_info,第7个
0006 //长度6个
3c 69 6e 69 74 3e //<init>
01 //utf8_info,第8个
0003 //长度3
28 29 56 //()V
01 //utf8_info,第9个
0004 //长度4
43 6f 64 65 //Code
01 //utf8_info,第10个
000f //长度15
4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 //LineNumberTable
01 //utf8_info,第11个
000a //长度10
74 65 73 74 4d 65 74 68 6f 64 //testMethod
01 //utf8_info,第12个
000a //长度10
53 6f 75 72 63 65 46 69 6c 65 //SourceFile
01 //utf8_info,第13个
0009 //长度9
44 65 6d 6f 2e 6a 61 76 61 //Demo.java
0c //NameAndType_info,第14个
0007 0008 //#7,#8
0c //NameAndType_info,第15个
0005 0006 //#5,#6
01 //utf8_info, 第16个
000d //长度13
63 6f 6d 2f 64 65 6d 6f 2f 44 65 6d 6f //值:com/demo/Demo
01 //utf8_info, 第17个
0010 //长度16
6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 // 值:java/lang/Object
----------------------常量池结束-----------------------------------
00 21 Access_Flag //访问标志
00 03 //类索引,引用#3号常量,com/demo/Demo
00 04 //父类索引,引用#4号常量
00 00 //接口0个
00 01 //1个field
00 02 //访问标识符:private
00 05 //name索引:#5
00 06 //描述索引:#6
00 00 //属性表数量0
00 //略
0200 0100 0700 0800 0100 0900 0000 2600
0200 0100 0000 0a2a b700 012a 04b5 0002
b100 0000 0100 0a00 0000 0a00 0200 0000
0300 0400 0400 0400 0b00 0800 0100 0900
0000 1900 0000 0100 0000 01b1 0000 0001
000a 0000 0006 0001 0000 0008 0001 000c
0000 0002 000d
4、分析的时候可以使用java自带的反编译器来解析字节码文件:javap -verbose Demo //不用带后缀.class
本文仅作个解析记录,完整的分析请移步:https://www.jianshu.com/p/252f381a6bc4