java class类结构

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. }    
相信学java的人都对new  Object();创建对象都很熟悉,但想要真正了解原理就没那么容易!以以下例子为例,解释class代码及执行过程,如有错误,还望各位高手多多指教!


public class Dog {
	public String name;
	public int age;
	public Dog() {
	}
	public Dog(String name)
	{
		this.name = name;
	}
	public Dog(String name, int age)
	{
		this.name = name;
		this.age = age;
	}
	public static void  getStaticValue(int j)
	{
		int i=j;
		System.out.println(i);
	}
	public  void  getValue(int j)
	{
		int i=j;
		System.out.println(i);
	}
	public static void main(String[] args) {
		try {
			new Dog().getValue(10);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
} 

如上代码很简单,main方法加上try catch只是为了  让大家看一下java文件生产字节码是怎么样的

执行javac  Dog.java文件,生成class文件。然后使用javap -verbose Dog反编译出class代码。

生成如下代码:

view plaincopy to clipboardprint?
Compiled from "Dog.java"  
public class Dog extends java.lang.Object   
  SourceFile: "Dog.java"  
  minor version: 0   // minor version: major version:这两个是表示class文件的版本号,                            
  major version: 50   //详细见http://blog.csdn.net/xiaxiaorui2003/archive/2009/07/07/4327029.aspx这位兄弟的blog   
  
  
  Constant pool:      //常量池,如下以const开头的都是常量池信息,每个class文件都有一些常量池信息   
                     //当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用   
                     //如下以#开头的表示偏移量编号,相当于id号,接下来解释如下代码的作用   
  
  
如下 #11.#31; 这段代码什么作用呢?很简单,就是表示创建Object对象。   
首先来看.号左边的#11,找到常量池中#11,跳到const #11 = class       #42;    //  java/lang/Object   
这个表示是一个Object类型,class后面的 #42;表示接下来要跳到常量池中#42  
找到const #42 = Asciz       java/lang/Object;  表示生成Object类型   
接下来看.号右边的#31。   
const #31 = NameAndType #16:#17;     //解释:这里指定到#16 #17   
const #16 = Asciz       <init>;   
const #17 = Asciz       ()V;      //解释:到这里完成初始化工作   
  
  
  
//NameAndType表示名字和类型   调用构造方法 的Name都是<init>,   V表示没有返回值     ,()  括号里面是空的表示没有参数   
//到这里完成Dog   
//   
如下有  :   
Method   //方法   
Field   //类名.属性   
class   //类型   
Asciz   //方法签名   
NameAndType   //变量名和类型   
  
java类型对应的class文件方法签名的标识符:   
invokespecial  //调用构造方法、父类方法   
invokevirtual  //调用普通方法(非构造方法、static方法)   
invokestatic   //调用static方法   
  
Ljava/lang/String;;  //这表示String类型,这里要全路径,java/lang/String;;前面的L表示非java八大基本类型   
void V   
int char byte short long float double 都是类型第一个字母(大写)   
boolean 比较特别,用Z表示  ,因为B被byte给占用了   
  
  
const #1 = Method       #11.#31;        //  java/lang/Object."<init>":()V     解释:初始化Object   
  
const #2 = Field        #6.#32; //  Dog.name:Ljava/lang/String;      Dog类中定义的String name   
const #3 = Field        #6.#33; //  Dog.age:I        Dog类中定义的int age   
const #4 = Field        #34.#35;        //  java/lang/System.out:Ljava/io/PrintStream;   
const #5 = Method       #36.#37;        //  java/io/PrintStream.println:(I)V      解释:调用println(int value), V表示返回值是void   
const #6 = class        #38;    //  Dog   
const #7 = Method       #6.#31; //  Dog."<init>":()V     解释:初始化Dog,调用构造函数,"<init>"是初始化标识符, V表示返回值是void   
const #8 = Method       #6.#39; //  Dog.getValue:(I)V      解释:调用getValue(int j)方法, V表示返回值是void   
const #9 = class        #40;    //  java/lang/Exception   
const #10 = Method      #9.#41; //  java/lang/Exception.printStackTrace:()V   
const #11 = class       #42;    //  java/lang/Object   
const #12 = Asciz       name;   
const #13 = Asciz       Ljava/lang/String;;   
const #14 = Asciz       age;   
const #15 = Asciz       I;   
const #16 = Asciz       <init>;   
const #17 = Asciz       ()V;   
const #18 = Asciz       Code;   
const #19 = Asciz       LineNumberTable;   
const #20 = Asciz       (Ljava/lang/String;)V;   
const #21 = Asciz       (Ljava/lang/String;I)V;   
const #22 = Asciz       getStaticValue;   
const #23 = Asciz       (I)V;   
const #24 = Asciz       getValue;   
const #25 = Asciz       main;   
const #26 = Asciz       ([Ljava/lang/String;)V;   
const #27 = Asciz       StackMapTable;   
const #28 = class       #40;    //  java/lang/Exception   
const #29 = Asciz       SourceFile;   
const #30 = Asciz       Dog.java;   
const #31 = NameAndType #16:#17;//  "<init>":()V   
const #32 = NameAndType #12:#13;//  name:Ljava/lang/String;   
const #33 = NameAndType #14:#15;//  age:I   
const #34 = class       #43;    //  java/lang/System   
const #35 = NameAndType #44:#45;//  out:Ljava/io/PrintStream;   
const #36 = class       #46;    //  java/io/PrintStream   
const #37 = NameAndType #47:#23;//  println:(I)V   
const #38 = Asciz       Dog;   
const #39 = NameAndType #24:#23;//  getValue:(I)V   
const #40 = Asciz       java/lang/Exception;   
const #41 = NameAndType #48:#17;//  printStackTrace:()V   
const #42 = Asciz       java/lang/Object;   
const #43 = Asciz       java/lang/System;   
const #44 = Asciz       out;   
const #45 = Asciz       Ljava/io/PrintStream;;   
const #46 = Asciz       java/io/PrintStream;   
const #47 = Asciz       println;   
const #48 = Asciz       printStackTrace;   
  
{   
public java.lang.String name;   
  
public int age;   
  
  
  
  
//如下的Locals表示方法内局部变量个数,该例中是1,有些人疑惑的是Dog()中明明没有参数啊,应该是0啊!   
//当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用   
//非static方法,在调用的时候都会给方法默认加上一个当前对象(this)类型的参数,不需要在方法中定义,   
//这个时候局部变量列表中index为0的位置保存的是this,其他索引号按变量定义顺序累加   
//static方法不依赖对象,所以不用传this   
//Args_size表示参数个数,public Dog();会传一个this进去,所以value是1   
public Dog();   
  Code:   
   Stack=1, Locals=1, Args_size=1       
   0:   aload_0    //加载局部变量表index为0的变量,在这里是this   
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V      //调用构造方法   
   4:   return  
  LineNumberTable:   
   line 6: 0  
   line 7: 4  
  
  
  
//这个构造方法与上个构造方法也是同理,只是多少个String参数和  给name赋值   
public Dog(java.lang.String);   
  Code:   
   Stack=2, Locals=2, Args_size=2  
   0:   aload_0   
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V        
                    //这里的#1;表示对常量池的引用,创建一个类,必须先初始化父类,创建Dog之前创建Object   
   4:   aload_0     //加载局部变量表index为0的变量,在这里是this   
   5:   aload_1     //加载局部变量表index为1的变量,在这里是String name局部变量   
   6:   putfield        #2; //Field name:Ljava/lang/String;   赋值操作   
   9:   return  
  LineNumberTable:   
   line 10: 0  
   line 11: 4  
   line 12: 9  
  
  
public Dog(java.lang.String, int);   
  Code:   
   Stack=2, Locals=3, Args_size=3  
   0:   aload_0   
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V   
   4:   aload_0   
   5:   aload_1   
   6:   putfield        #2; //Field name:Ljava/lang/String;   
   9:   aload_0   
   10:  iload_2   
   11:  putfield        #3; //Field age:I   
   14:  return  
  LineNumberTable:   
   line 15: 0  
   line 16: 4  
   line 17: 9  
   line 18: 14  
  
//这里的Args_size=1,是因为是static方法,不会传进this   
public static void getStaticValue(int);   
  Code:   
   Stack=2, Locals=2, Args_size=1  
   0:   iload_0   
   1:   istore_1     //istore_1其实是是有两部分组成,i表示int类型 ,1表示局部变量表中index为1。那合起来就是存储在局部变量表中,index为1的位置   
   2:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;         //引用常量池 #4;   
   5:   iload_1   
   6:   invokevirtual   #5; //Method java/io/PrintStream.println:(I)V     //引用常量池 #5;   
   9:   return  
  LineNumberTable:   
   line 21: 0  
   line 22: 2  
   line 23: 9  
  
  
public void getValue(int);   
  Code:   
   Stack=2, Locals=3, Args_size=2  
   0:   iload_1   
   1:   istore_2   
   2:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;   
   5:   iload_2   
   6:   invokevirtual   #5; //Method java/io/PrintStream.println:(I)V   
   9:   return  
  LineNumberTable:   
   line 26: 0  
   line 27: 2  
   line 28: 9  
  
  
public static void main(java.lang.String[]);   
  Code:   
   Stack=2, Locals=2, Args_size=1  
   0:   new     #6; //class Dog       解释:创建Dog   
   3:   dup       //复制引用到stack(栈)   
   4:   invokespecial   #7; //Method "<init>":()V   
   7:   bipush  10      //压入一个常量10   
   9:   invokevirtual   #8; //Method getValue:(I)V   
   12:  goto    20  
   15:  astore_1         
   16:  aload_1   
   17:  invokevirtual   #10; //Method java/lang/Exception.printStackTrace:()V   
   20:  return  
  Exception table:   
   from   to  target type   
     0    12    15   Class java/lang/Exception  //表示上面代码从1到12行之间如果发生Exception异常就goto到15处   
  
  
  
  LineNumberTable:   
   line 32: 0  
   line 35: 12  
   line 33: 15  
   line 34: 16  
   line 36: 20  
  
  
  
//如下这块我不太理解什么意思,加了try catch之后才出现这个的,还有如上的 Stack=    ,   
//这个不知道是什么意思,暂没有领悟 ,望高手指导
  StackMapTable: number_of_entries = 2  
   frame_type = 79 /* same_locals_1_stack_item */  
     stack = [ class java/lang/Exception ]   
   frame_type = 4 /* same */  
  
  
}  

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值