二、手动分析class文件
上面大致讲解了一下class文件的结构,这里,我们拿一个class文件做一个简单的分析,来验证上面的说法。
先看看一个简单的类
- public class Hello{
- private int test;
- public int test(){
- return test;
- }
- }
编译之后的class文件十六进制结果如下所示,可以用UE等十六进制编辑器打开:
- ca fe ba be 00 00 00 32 00 12 0a 00 04 00 0e 09
- 00 03 00 0f 07 00 10 07 00 11 01 00 04 74 65 73
- 74 01 00 01 49 01 00 06 3c 69 6e 69 74 3e 01 00
- 03 28 29 56 01 00 04 43 6f 64 65 01 00 0f 4c 69
- 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 01 00 03
- 28 29 49 01 00 0a 53 6f 75 72 63 65 46 69 6c 65
- 01 00 0a 48 65 6c 6c 6f 2e 6a 61 76 61 0c 00 07
- 00 08 0c 00 05 00 06 01 00 05 48 65 6c 6c 6f 01
- 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65
- 63 74 00 21 00 03 00 04 00 00 00 01 00 02 00 05
- 00 06 00 00 00 02 00 01 00 07 00 08 00 01 00 09
- 00 00 00 1d 00 01 00 01 00 00 00 05 2a b7 00 01
- b1 00 00 00 01 00 0a 00 00 00 06 00 01 00 00 00
- 01 00 01 00 05 00 0b 00 01 00 09 00 00 00 1d 00
- 01 00 01 00 00 00 05 2a b4 00 02 ac 00 00 00 01
- 00 0a 00 00 00 06 00 01 00 00 00 03 00 01 00 0c
- 00 00 00 02 00 0d
接下来我们就按照class文件的格式来分析上面的一串数字,还是按照之前的顺序来
1、魔数:cafebabe,这个是用来标识java class文件的,如果文件的开始不是cafebase的话,虚拟机会拒绝加载该文件。关于这个我们可以试验一下,用16进制编辑器修改cafebabe。
运行 java Hello
会抛出ClassFormatError
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value
2868820670 in class file Hello
2、接下来就是version字段:00 00 00 32,前两个字节00是minor_version,后两个字节0032是major_version字段,对应的十进制值为50,也就是说当前class文件的主版本号为50,次版本号为0。前面讲过,如果version字段不在当前虚拟机支持的范围之内,虚拟机会拒绝加载。我们可以试一下,把version字段改大,例如改成00 01 00 40(主版本号为64,次版本号为1)。加载该class文件,会抛出java.lang.UnsupportedClassVersionError: Hello : Unsupported major.minor version 64.1,表示当前虚拟机不支持64.1版本的class文件。
阅读(2662) | 评论(0) | 转发(3) |