我只是一个喜欢开发的测试,喜欢测试的开发,喜欢每天都知道得更多一些,更深入一些的感觉。。。。。
分类: Java
2013-09-03 13:41:15
1. Code属性中的code[]
1)
此即HelloWorld的构造函数public HelloWorld()。
偏移量 |
指令码 |
指令助记符 |
分析结果 |
0000 02ba |
0x2A |
aload_0 |
将第一个引用类型局部变量this推送至栈顶 |
0000 02bb |
0xB7000C |
invokespecial |
调用超类Object的构造方法java.lang.Object.
0xB7是invokespecial指令的指令码 |
0000 02be |
0xB1 |
return |
从当前方法返回void,即return; |
2) public java.lang.String getName();
偏移量 |
指令码 |
指令助记符 |
分析结果 |
0000 02f7 |
0x2A |
aload_0 |
将第一个引用类型局部变量this推送至栈顶 |
0000 02f8 |
0xB40014 |
getfield #20 |
获取指定类HelloWorld的实例域name,并将其值压入栈顶,其中: |
0000 02fb |
0xB0 |
areturn |
从当前方法返回对象引用 |
3) public void setName(java.lang.String);
偏移量 |
指令码 |
指令助记符 |
分析结果 |
0000 0334 |
0x2A |
aload_0 |
将第一个引用类型局部变量this推送至栈顶 |
0000 0335 |
0x2B |
aload_1 |
将第二个引用类型局部变量name推送至栈顶 |
0000 0336 |
0xB50014 |
putfield #20 |
为指定类HelloWorld的实例域name赋值,其中: |
0000 0339 |
0xB1 |
return |
从当前方法返回void |
4) public void printHello();
偏移量 |
指令码 |
指令助记符 |
分析结果 |
0000 0380 |
0xB20019 |
getstatic #25 |
获取指定类System的PrintStream类型静态域out,并将其值压入栈顶,其中: |
0000 0383 |
0xBB001F |
new #31 |
创建一个StringBuilder对象,并将其引用值压入栈顶,其中: |
0000 0386 |
0x59 |
dup |
复制栈顶数值并将复制值压入栈顶 |
0000 0387 |
0x1221 |
ldc #33 |
将String型常量值“Hello World,”从常量池中推送至栈顶,其中: |
0000 0389 |
0xB70023 |
invokespecial #35 |
调用超类StringBuilder实例初始化方法 |
0000 038c |
0x2A |
aload_0 |
将第一个引用类型局部变量this推送至栈顶 |
0000 038d |
0xB40014 |
getfield #20 |
获取指定类HelloWorld的实例域name,并将其值压入栈顶,其中: |
0000 0390 |
0xB60025 |
invokevirtual #37 |
调用StringBuilder实例的append()方法,其中: |
0000 0393 |
0xB60029 |
invokevirtual #41 |
调用StringBuilder实例的toString()方法,其中: |
0000 0396 |
0xB6002C |
invokevirtual #44 |
调用PrintStream实例System.out的println()方法,其中: |
0000 0399 |
0xB1 |
return |
从当前方法返回void |
偏移量 |
指令码 |
指令助记符 |
分析结果 |
0000 03d6 |
0xB20019 |
getstatic #25 |
获取指定类System的静态域out,并将其值压入栈顶,其中: |
0000 03d9 |
0xBB001F |
new #31 |
创建一个StringBuilder对象,并将其引用值压入栈顶,其中: |
0000 03dc |
0x59 |
dup |
复制栈顶数值并将复制值压入栈顶 |
0000 03dd |
0x1231 |
ldc #49 |
将String型常量值“Hello ,”从常量池中推送至栈顶,其中: |
0000 03df |
0xB70023 |
invokespecial #35 |
调用超类StringBuilder实例初始化方法 |
0000 03e2 |
0x2B |
aload_1 |
将第二个引用类型局部变量whoName推送至栈顶 |
0000 03e3 |
0xB60025 |
invokevirtual #37 |
调用StringBuilder实例的append()方法,其中: |
0000 03e6 |
0xB60029 |
invokevirtual #41 |
调用StringBuilder实例的toString()方法,其中: |
0000 03e9 |
0xB6002C |
invokevirtual #44 |
调用PrintStream实例的println()方法,其中: |
0000 03ec |
0xB1 |
return |
从当前方法返回void |
2. Code属性中的属性
本例的code中有两种属性:
1) LineNumberTable:用来表示源文件中的行号在code[]中的对应位置;
2) LocalVariableTable:方法中局部变量的信息。
1)
A. 属性1
偏移量 |
信息项 |
信息值 |
分析结果 |
|
0000 02c3 |
属性名索引 |
0x000E |
指向常量表第14个字符串表项,值为LineNumberTable |
|
0000 02c5 |
属性长度 |
0x00000006 |
6字节 |
|
0000 02c9 |
行号表长度 |
0x0001 |
1个表项 |
|
0000 02cb |
start_pc |
0x0000 |
指向code[0] |
源文件第4行从code[0]开始 |
0000 02cd |
行号 |
0x0004 |
源文件No.4行 |
B. 属性2
偏移量 |
信息项 |
信息值 |
分析结果 |
0000 02cf |
属性名索引 |
0x000F |
指向常量表第15个字符串表项,值为LocalVariableTable |
0000 02d1 |
属性长度 |
0x0000000C |
12字节 |
0000 02d5 |
局部变量表长度 |
0x0001 |
1个表项 |
0000 02d7 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[4]之间的范围内 |
0000 02d9 |
长度 |
0x0005 |
|
0000 02db |
名称索引 |
0x0010 |
指向常量表第16个字符串表项,值为this |
0000 02de |
描述符索引 |
0x0011 |
指向常量表第17个字符串表项,值为Lcom/momo/javatips/jmx/HelloWorld; |
0000 02e0 |
索引 |
0x0000 |
变量在当前栈帧的局部变量表中的索引 |
A. 属性1
偏移量 |
信息项 |
信息值 |
分析结果 |
|
0000 0300 |
属性名索引 |
0x000E |
指向常量表第14个字符串表项,值为LineNumberTable |
|
0000 0302 |
属性长度 |
0x00000006 |
6字节 |
|
0000 0306 |
行号表长度 |
0x0001 |
1个表项 |
|
0000 0308 |
start_pc |
0x0000 |
指向code[0] |
源文件第8行从code[0]开始 |
0000 030a |
行号 |
0x0008 |
源文件No.8行 |
B. 属性2
偏移量 |
信息项 |
信息值 |
分析结果 |
0000 030c |
属性名索引 |
0x000F |
指向常量表第15个字符串表项,值为LocalVariableTable |
0000 030e |
属性长度 |
0x0000000C |
12字节 |
0000 0312 |
局部变量表长度 |
0x0001 |
1个表项 |
0000 0314 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[4]之间的范围内 |
0000 0316 |
长度 |
0x0005 |
|
0000 0318 |
名称索引 |
0x0010 |
指向常量表第16个字符串表项,值为this |
0000 031a |
描述符索引 |
0x0011 |
指向常量表第17个字符串表项,值为Lcom/momo/javatips/jmx/HelloWorld; |
0000 031c |
索引 |
0x0000 |
变量在当前栈帧的局部变量表中的索引 |
3) public void setName(java.lang.String);
A. 属性1
偏移量 |
信息项 |
信息值 |
分析结果 |
||
0000 033e |
属性名索引 |
0x000E |
指向常量表第14个字符串表项,值为LineNumberTable |
||
0000 0340 |
属性长度 |
0x0000000A |
10字节 |
||
0000 0344 |
行号表长度 |
0x0002 |
2个表项 |
||
0000 0346 |
表项1 |
start_pc |
0x0000 |
指向code[0] |
源文件第12行从code[0]开始 |
0000 0348 |
行号 |
0x000C |
源文件No.12行 |
||
0000 034a |
表项2 |
start_pc |
0x0005 |
指向code[5] |
源文件第13行从code[5]开始 |
0000 034c |
行号 |
0x000D |
源文件No.13行 |
B. 属性2
偏移量 |
信息项 |
信息值 |
分析结果 |
|
0000 034e |
属性名索引 |
0x000F |
指向常量表第15个字符串表项,值为LocalVariableTable |
|
0000 0350 |
属性长度 |
0x00000016 |
22字节 |
|
0000 0354 |
局部变量表长度 |
0x0002 |
2个表项 |
|
0000 0356 |
表 项 1 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[5]之间的范围内 |
0000 0358 |
长度 |
0x0006 |
||
0000 035a |
名称索引 |
0x0010 |
指向常量表第16个字符串表项,值为this |
|
0000 035c |
描述符索引 |
0x0011 |
指向常量表第17个字符串表项,值为 Lcom/momo/javatips/jmx/HelloWorld; |
|
0000 035e |
索引 |
0x0000 |
变量在当前栈帧的局部变量表中的索引 |
|
0000 0360 |
表 项 2 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[5]之间的范围内 |
0000 0362 |
长度 |
0x0006 |
||
0000 0364 |
名称索引 |
0x0007 |
指向常量表第7个字符串表项,值为name |
|
0000 0366 |
描述符索引 |
0x0008 |
指向常量表第17个字符串表项,值为Ljava/lang/String; |
|
0000 0368 |
索引 |
0x0001 |
变量在当前栈帧的局部变量表中的索引 |
4) public void printHello();
A. 属性1
偏移量 |
信息项 |
信息值 |
分析结果 |
||
0000 039e |
属性名索引 |
0x000E |
指向常量表第14个字符串表项,值为LineNumberTable |
||
0000 03a0 |
属性长度 |
0x0000000A |
10字节 |
||
0000 03a4 |
行号表长度 |
0x0002 |
2个表项 |
||
0000 03a6 |
表项1 |
start_pc |
0x0000 |
指向code[0] |
源文件第16行从code[0]开始 |
0000 03a8 |
行号 |
0x0010 |
源文件No.16行 |
||
0000 03aa |
表项2 |
start_pc |
0x0019 |
指向code[25] |
源文件第17行从code[25]开始 |
0000 03ac |
行号 |
0x0011 |
源文件No.17行 |
B. 属性2
偏移量 |
信息项 |
信息值 |
分析结果 |
0000 03ae |
属性名索引 |
0x000F |
指向常量表第15个字符串表项,值为LocalVariableTable |
0000 03b0 |
属性长度 |
0x0000000C |
12字节 |
0000 03b4 |
局部变量表长度 |
0x0001 |
1个表项 |
0000 03b6 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[25]之间的范围内 |
0000 03b8 |
长度 |
0x001A |
|
0000 03ba |
名称索引 |
0x0010 |
指向常量表第16个字符串表项,值为this |
0000 03bc |
描述符索引 |
0x0011 |
指向常量表第17个字符串表项,值为Lcom/momo/javatips/jmx/HelloWorld; |
0000 03be |
索引 |
0x0000 |
变量在当前栈帧的局部变量表中的索引 |
A. 属性1
偏移量 |
信息项 |
信息值 |
分析结果 |
||
0000 03f1 |
属性名索引 |
0x000E |
指向常量表第14个字符串表项,值为LineNumberTable |
||
0000 03f3 |
属性长度 |
0x0000000A |
10字节 |
||
0000 03f7 |
行号表长度 |
0x0002 |
2个表项 |
||
0000 03f9 |
表项1 |
start_pc |
0x0000 |
指向code[0] |
源文件第20行从code[0]开始 |
0000 03fb |
行号 |
0x0014 |
源文件No.20行 |
||
0000 03fd |
表项2 |
start_pc |
0x0016 |
指向code[22] |
源文件第21行从code[22]开始 |
0000 03ff |
行号 |
0x0015 |
源文件No.21行 |
B. 属性2
偏移量 |
信息项 |
信息值 |
分析结果 |
|
0000 0401 |
属性名索引 |
0x000F |
指向常量表第15个字符串表项,值为LocalVariableTable |
|
0000 0403 |
属性长度 |
0x00000016 |
22字节 |
|
0000 0407 |
局部变量表长度 |
0x0002 |
2个表项 |
|
0000 0409 |
表 项 1 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[22]之间的范围内 |
0000 040b |
长度 |
0x0017 |
||
0000 040d |
名称索引 |
0x0010 |
指向常量表第16个字符串表项,值为this |
|
0000 040f |
描述符索引 |
0x0011 |
指向常量表第17个字符串表项,值为Lcom/momo/javatips/jmx/HelloWorld; |
|
0000 0411 |
索引 |
0x0000 |
变量在当前栈帧的局部变量表中的索引 |
|
0000 0413 |
表 项 2 |
start_pc |
0x0000 |
局部变量的作用域在code[0]至code[22]之间的范围内 |
0000 0415 |
长度 |
0x0017 |
||
0000 0417 |
名称索引 |
0x0033 |
指向常量表第51个字符串表项,值为whoName |
|
0000 0419 |
描述符索引 |
0x0008 |
指向常量表第17个字符串表项,值为Ljava/lang/String; |
|
0000 041b |
索引 |
0x0001 |
变量在当前栈帧的局部变量表中的索引 |
参考文献
1. 《深入理解Java虚拟机:JVM高级特性与最佳实践》 周志明 著,机械工业出版社,2011
2. 《Java虚拟机规范(Java SE 7版)》 Tim Lindholm,Frank Yellin,Gilad Bracha,Alex Buckley 著,周志明,吴璞渊,冶秀刚
译,2011
3. 《深入java虚拟机(第二版)》 [美]Bill Venners 著, 曹晓钢,蒋靖 译,机械工业出版社,2003