jvm简介-class文件格式解析示例

环境
JDK 1.6.0_10-rc2
源代码
/**
* 验证java class文件格式格式
* 以下代码不要修改:
* @author: zhanglixin
* @version: 1.0 2013-1-10
*/
public class ClassFormat1 implements Serializable{
final int C=8;
final String S="Hello!";
private double instaneDouble=1.01;
static double staticDouble = 2.02;
public static void main(String[] args)
{
boolean localBln = true;
}
}
编译后字节码
通过javap -version 查看

E:\testspace\jvm>javap -verbose ClassFormat1
Compiled from "ClassFormat1.java"
public class ClassFormat1 extends java.lang.Object implements java.io.Serializable
SourceFile: "ClassFormat1.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #12.#32; // java/lang/Object."":()V
const #2 = Field #11.#33; // ClassFormat1.C:I
const #3 = String #34; // Hello!
const #4 = Field #11.#35; // ClassFormat1.S:Ljava/lang/String;
const #5 = double 1.01d;
const #7 = Field #11.#36; // ClassFormat1.instaneDouble:D
const #8 = double 2.02d;
const #10 = Field #11.#37; // ClassFormat1.staticDouble:D
const #11 = class #38; // ClassFormat1
const #12 = class #39; // java/lang/Object
const #13 = class #40; // java/io/Serializable
const #14 = Asciz C;
const #15 = Asciz I;
const #16 = Asciz ConstantValue;
const #17 = int 8;
const #18 = Asciz S;
const #19 = Asciz Ljava/lang/String;;
const #20 = Asciz instaneDouble;
const #21 = Asciz D;
const #22 = Asciz staticDouble;
const #23 = Asciz ;
const #24 = Asciz ()V;
const #25 = Asciz Code;
const #26 = Asciz LineNumberTable;
const #27 = Asciz main;
const #28 = Asciz ([Ljava/lang/String;)V;
const #29 = Asciz ;
const #30 = Asciz SourceFile;
const #31 = Asciz ClassFormat1.java;
const #32 = NameAndType #23:#24;// "":()V
const #33 = NameAndType #14:#15;// C:I
const #34 = Asciz Hello!;
const #35 = NameAndType #18:#19;// S:Ljava/lang/String;
const #36 = NameAndType #20:#21;// instaneDouble:D
const #37 = NameAndType #22:#21;// staticDouble:D
const #38 = Asciz ClassFormat1;
const #39 = Asciz java/lang/Object;
const #40 = Asciz java/io/Serializable;

{
final int C;
Constant value: int 8
final java.lang.String S;
Constant value: String Hello!
static double staticDouble;

public ClassFormat1();
Code:
Stack=3, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: aload_0
5: bipush 8
7: putfield #2; //Field C:I
10: aload_0
11: ldc #3; //String Hello!
13: putfield #4; //Field S:Ljava/lang/String;
16: aload_0
17: ldc2_w #5; //double 1.01d
20: putfield #7; //Field instaneDouble:D
23: return
LineNumberTable:
line 37: 0
line 38: 4
line 39: 10
line 40: 16


public static void main(java.lang.String[]);
Code:
Stack=1, Locals=2, Args_size=1
0: iconst_1
1: istore_1
2: return
LineNumberTable:
line 44: 0
line 45: 2


static {};
Code:
Stack=2, Locals=0, Args_size=0
0: ldc2_w #8; //double 2.02d
3: putstatic #10; //Field staticDouble:D
6: return
LineNumberTable:
line 41: 0

}
class文件分析
0X00000000h 偏移0-3:魔法数字。
0X00000000h 偏移4-5:次版本号。
0X00000000h 偏移5-6:主版本号。
0X00000000h 偏移8-9:常量池个数。算法:当前16进制转换为10进制-1。
0X00000000h 偏移A 至 0X00000160h 偏移8:常量池。
0X00000160h 偏移9-A:Access flag类访问修饰符
0X00000160h 偏移B-C:当前类名字索引
0X00000160h 偏移D-E:父类名字索引
0X00000160h 偏移F- 0X00000170h 偏移 0 :该类实现的接口数量。值00 001,1个。
0X00000170h 偏移1-2:接口名字索引。值00 0D,索引值13.即对应常量池索引号13的项,即该接口名字。
0X00000170h 偏移3- 至 0X00000200 偏移4:为域Field的信息
0X00000170h 偏移3-4 :域的数量。值00 04,即4个域。
0X00000170h 偏移5-6 :第一个域的访问修饰(Access Flag),值:00 10,即ACC_FINAL,final方法,不可覆盖。
0X00000170h 偏移7-8 :域名字索引。值00 0E,即对应常量池第14项,即“C”,域的名字为C 。
0X00000170h 偏移9-a :域名字的描述符。值00 0F,即对应常量池第15项,即“I”,域的类型为Integter 整型。
0X00000170h 偏移b-c :该域所含属性的数量。值00 01,含有一个属性。
0X00000170h 偏移d-e :该属性的名字索引。值00 10,即对应常量池16项,即:ConstantValue.该属性值为常量值。
0X00000170h 偏移f- 0X00000180h 偏移2 :属性的长度,值 00 00 00 02,即4个字节长。
0X00000180h 偏移3-4:属性值 00 11,即对应常量池的索引是17,为:“int 8”。
以下各个域相同。
0X00000180h 偏移5 至 0X00000190 偏移4 :第二个域 final String S="Hello!"的域。
0X00000190h 偏移5 至 0X00000190 偏移c :第三个域 private double instaneDouble=1.01 的域。注意该域没有属性集合。
0X00000190h 偏移d 至 0X000001a0 偏移4 :第四个域 static double staticDouble = 2.02 的域。注意该域没有属性集合。
0X000001a0 偏移5 - 0X00000240h 偏移0 :为方法method的信息。
0X000001a0h 偏移5-6 :方法的数量。值00 03,即3个方法。
0X000001a0h 偏移7-8 :第一个方法的访问修饰(Access Flag),值:00 01,即ACC_PUBLIC,public方法。
0X000001a0h 偏移9-a :方法名字索引。值00 17,即对应常量池第23项,即“”,对象实例初始化方法 。
0X000001a0h 偏移b-c :方法名字的描述符。值00 18,即对应常量池第24项,即“()V",方法的参数为空,返回值void。
0X000001a0h 偏移d-e :该方法所含属性的数量。值00 01,含有一个属性。
0X000001a0h 偏移f- 0X000001b0h 偏移 0:该属性的名字索引。值00 19,即对应常量池25项,即:"Code".该属性值为代码。
0X000001b0h 偏移1-4 :属性的长度,值 00 00 00 3c,4个字节长,该属性的长度,3c,即60字节(单位u1),后续60个字节为属性值。
0X000001b0h 偏移3- 0X000001f0h 偏移0:为属性值,即该方法的字节码指令。
以下各个方法相同。
0X000001f0h 偏移1- 0X00000210h偏移d 第二个方法,main方法
0X00000210h 偏移e- 0X00000240h偏移a 第三个方法,方法,类初始化方法。
0X00000240h偏移b-0X00000250h 偏移4(文件结尾) :为属性的信息
0X00000240h 偏移b-c :属性的数量。值00 01,即1个属性。
0X00000240h 偏移d-e :第一个属性的索引值,值:00 1e,对应常量池第30项,值为:"SourceFile"。
0X00000240h 偏移f- 0X00000250h 偏移2:属性值长度 00 00 00 02,长度为2个u1。
0X00000250h 偏移3-4: 属性值为 00 1F ,值为31,对应常量值第31项,为:“ClassFormat1.java”

你可能感兴趣的:(jvm虚拟机)