class文件格式如下:

Java代码 复制代码 收藏代码
  1. 相信学java的人都对new  Object();创建对象都很熟悉,但想要真正了解原理就没那么容易!以以下例子为例,解释class代码及执行过程,如有错误,还望各位高手多多指教!   
  2.   
  3.   
  4. public class Dog {   
  5.     public String name;   
  6.     public int age;   
  7.     public Dog() {   
  8.     }   
  9.     public Dog(String name)   
  10.     {   
  11.         this.name = name;   
  12.     }   
  13.     public Dog(String name, int age)   
  14.     {   
  15.         this.name = name;   
  16.         this.age = age;   
  17.     }   
  18.     public static void  getStaticValue(int j)   
  19.     {   
  20.         int i=j;   
  21.         System.out.println(i);   
  22.     }   
  23.     public  void  getValue(int j)   
  24.     {   
  25.         int i=j;   
  26.         System.out.println(i);   
  27.     }   
  28.     public static void main(String[] args) {   
  29.         try {   
  30.             new Dog().getValue(10);   
  31.         } catch (Exception e) {   
  32.             e.printStackTrace();   
  33.         }   
  34.     }   
  35. }    
  36.   
  37. 如上代码很简单,main方法加上try catch只是为了  让大家看一下java文件生产字节码是怎么样的   
  38.   
  39. 执行javac  Dog.java文件,生成class文件。然后使用javap -verbose Dog反编译出class代码。   
  40.   
  41. 生成如下代码:   
  42.   
  43. view plaincopy to clipboardprint?   
  44. Compiled from "Dog.java"     
  45. public class Dog extends java.lang.Object      
  46.   SourceFile: "Dog.java"     
  47.   minor version: 0   // minor version: major version:这两个是表示class文件的版本号,                               
  48.   major version: 50   //详细见http://blog.csdn.net/xiaxiaorui2003/archive/2009/07/07/4327029.aspx这位兄弟的blog      
  49.      
  50.      
  51.   Constant pool:      //常量池,如下以const开头的都是常量池信息,每个class文件都有一些常量池信息      
  52.                      //当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用      
  53.                      //如下以#开头的表示偏移量编号,相当于id号,接下来解释如下代码的作用      
  54.      
  55.      
  56. 如下 #11.#31; 这段代码什么作用呢?很简单,就是表示创建Object对象。      
  57. 首先来看.号左边的#11,找到常量池中#11,跳到const #11 = class       #42;    //  java/lang/Object      
  58. 这个表示是一个Object类型,class后面的 #42;表示接下来要跳到常量池中#42     
  59. 找到const #42 = Asciz       java/lang/Object;  表示生成Object类型      
  60. 接下来看.号右边的#31。      
  61. const #31 = NameAndType #16:#17;     //解释:这里指定到#16 #17      
  62. const #16 = Asciz       <init>;      
  63. const #17 = Asciz       ()V;      //解释:到这里完成初始化工作      
  64.      
  65.      
  66.      
  67. //NameAndType表示名字和类型   调用构造方法 的Name都是<init>,   V表示没有返回值     ,()  括号里面是空的表示没有参数      
  68. //到这里完成Dog      
  69. //      
  70. 如下有  :      
  71. Method   //方法      
  72. Field   //类名.属性      
  73. class   //类型      
  74. Asciz   //方法签名      
  75. NameAndType   //变量名和类型      
  76.      
  77. java类型对应的class文件方法签名的标识符:      
  78. invokespecial  //调用构造方法、父类方法      
  79. invokevirtual  //调用普通方法(非构造方法、static方法)      
  80. invokestatic   //调用static方法      
  81.      
  82. Ljava/lang/String;;  //这表示String类型,这里要全路径,java/lang/String;;前面的L表示非java八大基本类型      
  83. void V      
  84. int char byte short long float double 都是类型第一个字母(大写)      
  85. boolean 比较特别,用Z表示  ,因为B被byte给占用了      
  86.      
  87.      
  88. const #1 = Method       #11.#31;        //  java/lang/Object."<init>":()V     解释:初始化Object      
  89.      
  90. const #2 = Field        #6.#32//  Dog.name:Ljava/lang/String;      Dog类中定义的String name      
  91. const #3 = Field        #6.#33//  Dog.age:I        Dog类中定义的int age      
  92. const #4 = Field        #34.#35;        //  java/lang/System.out:Ljava/io/PrintStream;      
  93. const #5 = Method       #36.#37;        //  java/io/PrintStream.println:(I)V      解释:调用println(int value), V表示返回值是void      
  94. const #6 = class        #38;    //  Dog      
  95. const #7 = Method       #6.#31//  Dog."<init>":()V     解释:初始化Dog,调用构造函数,"<init>"是初始化标识符, V表示返回值是void      
  96. const #8 = Method       #6.#39//  Dog.getValue:(I)V      解释:调用getValue(int j)方法, V表示返回值是void      
  97. const #9 = class        #40;    //  java/lang/Exception      
  98. const #10 = Method      #9.#41//  java/lang/Exception.printStackTrace:()V      
  99. const #11 = class       #42;    //  java/lang/Object      
  100. const #12 = Asciz       name;      
  101. const #13 = Asciz       Ljava/lang/String;;      
  102. const #14 = Asciz       age;      
  103. const #15 = Asciz       I;      
  104. const #16 = Asciz       <init>;      
  105. const #17 = Asciz       ()V;      
  106. const #18 = Asciz       Code;      
  107. const #19 = Asciz       LineNumberTable;      
  108. const #20 = Asciz       (Ljava/lang/String;)V;      
  109. const #21 = Asciz       (Ljava/lang/String;I)V;      
  110. const #22 = Asciz       getStaticValue;      
  111. const #23 = Asciz       (I)V;      
  112. const #24 = Asciz       getValue;      
  113. const #25 = Asciz       main;      
  114. const #26 = Asciz       ([Ljava/lang/String;)V;      
  115. const #27 = Asciz       StackMapTable;      
  116. const #28 = class       #40;    //  java/lang/Exception      
  117. const #29 = Asciz       SourceFile;      
  118. const #30 = Asciz       Dog.java;      
  119. const #31 = NameAndType #16:#17;//  "<init>":()V      
  120. const #32 = NameAndType #12:#13;//  name:Ljava/lang/String;      
  121. const #33 = NameAndType #14:#15;//  age:I      
  122. const #34 = class       #43;    //  java/lang/System      
  123. const #35 = NameAndType #44:#45;//  out:Ljava/io/PrintStream;      
  124. const #36 = class       #46;    //  java/io/PrintStream      
  125. const #37 = NameAndType #47:#23;//  println:(I)V      
  126. const #38 = Asciz       Dog;      
  127. const #39 = NameAndType #24:#23;//  getValue:(I)V      
  128. const #40 = Asciz       java/lang/Exception;      
  129. const #41 = NameAndType #48:#17;//  printStackTrace:()V      
  130. const #42 = Asciz       java/lang/Object;      
  131. const #43 = Asciz       java/lang/System;      
  132. const #44 = Asciz       out;      
  133. const #45 = Asciz       Ljava/io/PrintStream;;      
  134. const #46 = Asciz       java/io/PrintStream;      
  135. const #47 = Asciz       println;      
  136. const #48 = Asciz       printStackTrace;      
  137.      
  138. {      
  139. public java.lang.String name;      
  140.      
  141. public int age;      
  142.      
  143.      
  144.      
  145.      
  146. //如下的Locals表示方法内局部变量个数,该例中是1,有些人疑惑的是Dog()中明明没有参数啊,应该是0啊!      
  147. //当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用      
  148. //非static方法,在调用的时候都会给方法默认加上一个当前对象(this)类型的参数,不需要在方法中定义,      
  149. //这个时候局部变量列表中index为0的位置保存的是this,其他索引号按变量定义顺序累加      
  150. //static方法不依赖对象,所以不用传this      
  151. //Args_size表示参数个数,public Dog();会传一个this进去,所以value是1      
  152. public Dog();      
  153.   Code:      
  154.    Stack=1, Locals=1, Args_size=1          
  155.    0:   aload_0    //加载局部变量表index为0的变量,在这里是this      
  156.    1:   invokespecial   #1//Method java/lang/Object."<init>":()V      //调用构造方法      
  157.    4:   return     
  158.   LineNumberTable:      
  159.    line 60     
  160.    line 74     
  161.      
  162.      
  163.      
  164. //这个构造方法与上个构造方法也是同理,只是多少个String参数和  给name赋值      
  165. public Dog(java.lang.String);      
  166.   Code:      
  167.    Stack=2, Locals=2, Args_size=2     
  168.    0:   aload_0      
  169.    1:   invokespecial   #1//Method java/lang/Object."<init>":()V           
  170.                     //这里的#1;表示对常量池的引用,创建一个类,必须先初始化父类,创建Dog之前创建Object      
  171.    4:   aload_0     //加载局部变量表index为0的变量,在这里是this      
  172.    5:   aload_1     //加载局部变量表index为1的变量,在这里是String name局部变量      
  173.    6:   putfield        #2//Field name:Ljava/lang/String;   赋值操作      
  174.    9:   return     
  175.   LineNumberTable:      
  176.    line 100     
  177.    line 114     
  178.    line 129     
  179.      
  180.      
  181. public Dog(java.lang.String, int);      
  182.   Code:      
  183.    Stack=2, Locals=3, Args_size=3     
  184.    0:   aload_0      
  185.    1:   invokespecial   #1//Method java/lang/Object."<init>":()V      
  186.    4:   aload_0      
  187.    5:   aload_1      
  188.    6:   putfield        #2//Field name:Ljava/lang/String;      
  189.    9:   aload_0      
  190.    10:  iload_2      
  191.    11:  putfield        #3//Field age:I      
  192.    14:  return     
  193.   LineNumberTable:      
  194.    line 150     
  195.    line 164     
  196.    line 179     
  197.    line 1814     
  198.      
  199. //这里的Args_size=1,是因为是static方法,不会传进this      
  200. public static void getStaticValue(int);      
  201.   Code:      
  202.    Stack=2, Locals=2, Args_size=1     
  203.    0:   iload_0      
  204.    1:   istore_1     //istore_1其实是是有两部分组成,i表示int类型 ,1表示局部变量表中index为1。那合起来就是存储在局部变量表中,index为1的位置      
  205.    2:   getstatic       #4//Field java/lang/System.out:Ljava/io/PrintStream;         //引用常量池 #4;      
  206.    5:   iload_1      
  207.    6:   invokevirtual   #5//Method java/io/PrintStream.println:(I)V     //引用常量池 #5;      
  208.    9:   return     
  209.   LineNumberTable:      
  210.    line 210     
  211.    line 222     
  212.    line 239     
  213.      
  214.      
  215. public void getValue(int);      
  216.   Code:      
  217.    Stack=2, Locals=3, Args_size=2     
  218.    0:   iload_1      
  219.    1:   istore_2      
  220.    2:   getstatic       #4//Field java/lang/System.out:Ljava/io/PrintStream;      
  221.    5:   iload_2      
  222.    6:   invokevirtual   #5//Method java/io/PrintStream.println:(I)V      
  223.    9:   return     
  224.   LineNumberTable:      
  225.    line 260     
  226.    line 272     
  227.    line 289     
  228.      
  229.      
  230. public static void main(java.lang.String[]);      
  231.   Code:      
  232.    Stack=2, Locals=2, Args_size=1     
  233.    0:   new     #6//class Dog       解释:创建Dog      
  234.    3:   dup       //复制引用到stack(栈)      
  235.    4:   invokespecial   #7//Method "<init>":()V      
  236.    7:   bipush  10      //压入一个常量10      
  237.    9:   invokevirtual   #8//Method getValue:(I)V      
  238.    12:  goto    20     
  239.    15:  astore_1            
  240.    16:  aload_1      
  241.    17:  invokevirtual   #10//Method java/lang/Exception.printStackTrace:()V      
  242.    20:  return     
  243.   Exception table:      
  244.    from   to  target type      
  245.      0    12    15   Class java/lang/Exception  //表示上面代码从1到12行之间如果发生Exception异常就goto到15处      
  246.      
  247.      
  248.      
  249.   LineNumberTable:      
  250.    line 320     
  251.    line 3512     
  252.    line 3315     
  253.    line 3416     
  254.    line 3620     
  255.      
  256.      
  257.      
  258. //如下这块我不太理解什么意思,加了try catch之后才出现这个的,还有如上的 Stack=    ,      
  259. //这个不知道是什么意思,暂没有领悟 ,望高手指导   
  260.   StackMapTable: number_of_entries = 2     
  261.    frame_type = 79 /* same_locals_1_stack_item */     
  262.      stack = [ class java/lang/Exception ]      
  263.    frame_type = 4 /* same */     
  264.      
  265.      
  266. }