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”

你可能感兴趣的:(java虚拟机,class文件格式,class解析,常量池,jvm,字节码)