博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java class类结构
阅读量:4146 次
发布时间:2019-05-25

本文共 14053 字,大约阅读时间需要 46 分钟。

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       
; const #17 = Asciz ()V; //解释:到这里完成初始化工作 //NameAndType表示名字和类型 调用构造方法 的Name都是
, 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."
":()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."
":()V 解释:初始化Dog,调用构造函数,"
"是初始化标识符, 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
; 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;// "
":()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."
":()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."
":()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."
":()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 "
":()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 */ }

 

你可能感兴趣的文章
ABCNN: Attention-Based Convolutional Neural Network for Modeling Sentence Pairs论文解读
查看>>
词向量相关总结
查看>>
CUDA ERROR: device-side assert triggered问题解决思路
查看>>
Double Anchor R-CNN for Human Detection in a Crowd论文笔记
查看>>
行人检测几篇论文相关笔记
查看>>
视频超分辨率论文笔记
查看>>
图像超分辨率论文笔记
查看>>
MuCAN: Multi-Correspondence Aggregation Network for Video Super-Resolution论文笔记
查看>>
RealSR算法汇总
查看>>
文字图像超分辨率论文笔记
查看>>
deepinV20 显卡驱动 cuda10.2+cudnn配置
查看>>
You Only Look One-level Feature(YOLOF)
查看>>
opencv+libtorch c++工程问题及解决方案
查看>>
UFLDL softmax回归编程答案
查看>>
UFLDL self-taught自我学习编程答案
查看>>
UFLDL stackedae_exercise编程答案
查看>>
TensorFlow-1 入门
查看>>
python命令行解析模块argparse
查看>>
TensorFlow插曲之 tf.app.run()
查看>>
TensorFlow 插曲-- tf.placeholder 与 tf.Variable
查看>>