【Java精品源码栏目提醒】:网学会员鉴于大家对Java精品源码十分关注,论文会员在此为大家搜集整理了“java字节码解析--class结构 - 其它资料”一文,供大家参考学习
置顶
java 字节码解析--class 结构2010-09-10 00:26 459 人阅读 评论2 收藏 举报相信学
java 的人都对 new Object创建对象都很熟悉,但想要真正了解原理就没那么容易!以以下例子为例,解释 class 代码及执行过程,如有错误,还望各位高手多多指教!帧的创建如下所示:class 文件格式如下:程序计数器(pc):每一个
Java 线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令,对于非 Native 方法,这个区域记录的是正在执行的VM 原语的地址,如果正在执行的是 Natvie 方法,这个区域则为空(undefined)。
程序计数器 例子和图就拿现成的了,直接引用同事的
java view plaincopyprint 1. public class Demo 2. public static void foo 3. int a 1 4. int b 2 5. int c a b 5 6. 7. 接下来来看一个例子,源代码如下:
java view plaincopyprint 1. public class Dog 2. public String name 3. public int age 4. public Dog 5. 6. public DogString name 7. 8. this.name name 9. 10. public DogString name int age 11. 12. this.name name 13. this.age age 14. 15. public static void getStaticValueint j 16. 17. int ij 18. System.out.printlni 19. 20. public void getValueint j 21. 22. int ij 23. System.out.printlni 24. 25. public static void mainString args 26. try 27. new Dog.getValue10 28. catch Exception e 29. e.printStackTrace 30. 31. 32.如上代码很简单,main 方法加上 try catch 只是为了 让大家看一下
java 文件生产字节码是怎么样的执行 javac Dog.
java 文件,生成 class 文件。
然后使用 javap -verbose Dog反编译出 class 代码。
生成如下代码:
java view plaincopyprint 1. Compiled from Dog.
java 2. public class Dog extends
java.lang.Object 3. SourceFile: Dog.
java 4. minor version: 0 // minor version: major version:这两个是表 示 class 文件的主要、副版本号, 5. major version: 50 //详细见 http://blog.csdn.net/xiaxiaorui2003/archive/2009/07/07/4327029. aspx 这位兄弟的 blog 6. Constant pool: //常量池, 如下以 const 开头的都是常量池信息 每个 class 文件都有一些常量池信息 7. //当线程调用一个方法的时候,jvm 会开辟一个 帧出来,这个帧包括操作栈、局部变量列表、常量池的引用 8. //如下以开头的表示偏移量编号, 相当于 id 号, 接下来解释如下代码的作用 9. 如下 11.31 这段代码什么作用呢?很简单,就是表示创建 Object 对 象。
10.首先来看.号左边的11,找到常量池中11,跳到 const 11 class 42 //
java/lang/Object 11.这个表示是一个 Object 类型,class 后面的 42表示接下来要跳到常量 池中42 12.找到 const 42 Asciz
java/lang/Object 表示生成 Object 类型 13.接下来看.号右边的31。
14.const 31 NameAndType 16:17 //解释:这里指定到 16 17 15.const 16 Asciz 16.const 17 Asciz V //解释:到这里完成初始化工 作 17.//NameAndType 表示名字和类型 调用构造方法 的 Name 都是 , V 表示没有返回值 , 括号里面是空的表示没有参 数 18.//到这里完成 Dog 19.// 20.如下有 : 21.Method //方法 22.Field //类名.属性 23.class //类型 24.Asciz //方法签名 25.NameAndType //变量名和类型 26.
java 类型对应的 class 文件方法签名的标识符: 27.invokespecial //调用构造方法、父类方法 28.invokevirtual //调用普通方法(非构造方法、static 方法)29.invokestatic //调用 static 方法30.Ljava/lang/String //这表示 String 类型,这里要全路径,
java/lang/String前面的 L 表示非
java 八大基本类型31.void V32.int char byte short long float double 都是类型第一个字母(大 写)33.boolean 比较特别,用 J 表示 ,因为 B 被 byte 给占用了34.const 1 Method 11.31 //
java/lang/Object. init:V 解释:初始化 Object35.const 2 Field 6.32 // Dog.name:Ljava/lang/String Dog 类中定义的 String name36.const 3 Field 6.33 // Dog.age:I Dog 类中定 义的 int age37.const 4 Field 34.35 //
java/lang/System.ou t:Ljava/io/PrintStream38.const 5 Method 36.37 //
java/io/PrintStream .println:IV 解释:调用 printlnint value, V 表示返回值是 void39.const 6 class 38 // Dog40.const 7 Method 6.31 // Dog.:V 解释: 初始化 Dog,调用构造函数,是初始化标识符, V 表示返回值是 void41.const 8 Method 6.39 // Dog.getValue:IV 解 释:调用 getValueint j方法, V 表示返回值是 void42.const 9 class 40 //
java/lang/Exception43.const 10 Method 9.41 //
java/lang/Exception.printSt ackTrace:V44.const 11 class 42 //
java/lang/Object45.const 12 Asciz name46.const 13 Asciz Ljava/lang/String47.const 14 Asciz age48.const 15 Asciz I49.const 16 Asciz 50.const 17 Asciz V51.const 18 Asciz Code52.const 19 Asciz LineNumberTable53.const 20 Asciz Ljava/lang/StringV54.const 21 Asciz Ljava/lang/StringIV55.const 22 Asciz getStaticValue56.const 23 Asciz IV57.const 24 Asciz getValue58.const 25 Asciz main59.const 26 Asciz Ljava/lang/StringV60.const 27 Asciz StackMapTable61.const 28 class 40 //
java/lang/Exception62.const 29 Asciz SourceFile63.const 30 Asciz Dog.
java64.const 31 NameAndType 16:17// :V65.const 32 NameAndType 12:13// name:Ljava/lang/String66.const 33 NameAndType 14:15// age:I67.const 34 class 43 //
java/lang/System68.const 35 NameAndType 44:45// out:Ljava/io/PrintStream69.const 36 class 46 //
java/io/PrintStream70.const 37 NameAndType 47:23// println:IV71.const 38 Asciz Dog72.const 39 NameAndType 24:23// getValue:IV73.const 40 Asciz
java/lang/Exception74.const 41 NameAndType 48:17// printStackTrace:V75.const 42 Asciz
java/lang/Object76.const 43 Asciz
java/lang/System77.const 44 Asciz out78.const 45 Asciz Ljava/io/PrintStream79.const 46 Asciz
java/io/PrintStream80.const 47 Asciz println81.const 48 Asciz printStackTrace82.83.public
java.lang.String name84.public int age85.86.//如下的 Locals 表示方法内局部变量个数,该例中是 1,有些人疑惑的 是 Dog中明明没有参数啊,应该是 0 啊!87.//当线程调用一个方法的时候,jvm 会开辟一个帧出来,这个帧包括操作 栈、局部变量列表、常量池的引用88.//非 static 方法,在调用的时候都会给方法默认加上一个当前对象 (this)类型的参数,不需要在方法中定义,89.//这个时候局部变量列表中 index 为 0 的位置保存的是 this,其他索引 号按变量定义顺序累加90.//static 方法不依赖对象,所以不用传 this91.//Args_size 表示参数个数,public Dog会传一个 this 进去,所以 value 是 192.public Dog93. Code:94. Stack1 Locals1 Args_size195. 0: aload_0 //加载局部变量表 index 为 0 的变量,在这里是 this96. 1: invokespecial 1 //Method
java/lang/Object.: V //调用构造方法97. 4: return98. LineNumberTable: //见如上的 class 文件结构图99. line 6: 0100. line 7: 4101. LocalVariableTable: //见如上的 class 文件结构图102. Start Length Slot Name Signature103. 0 5 0 this LDog104. //这个构造方法与上个构造方法也是同理,只是多少个 String 参数 和 给 name 赋值105. public Dogjava.lang.String106. Code:107. Stack2 Locals2 Args_size2108. 0: aload_0109. 1: invokespecial 1 //Method
java/lang/Object.:V110. //这里的1表示对常量池的引用,创建一个 类,必须先初始化父类,创建 Dog 之前创建 Object111. 4: aload_0 //加载局部变量表 index 为 0 的变量,在这 里是 this112. 5: aload_1 //加载局部变量表 index 为 1 的变量,在这 里是 String name 局部变量113. 6: putfield 2 //Field name:Ljava/lang/String 赋值操作114. 9: return115. LineNumberTable:116. line 10: 0117. line 11: 4118. line 12: 9119. LocalVariableTable:120. Start Length Slot Name Signature121. 0 10 0 this LDog122. 0 10 1 name Ljava/lang/String123. public Dogjava.lang.String int124. Code:125. Stack2 Locals3 Args_size3126. 0: aload_0127. 1: invokespecial 1 //Method
java/lang/Object.:V128. 4: aload_0129. 5: aload_1130. 6: putfield 2 //Field name:Ljava/lang/String 131. 9: aload_0132. 10: iload_2133. 11: putfield 3 //Field age:I134. 14: return135. LineNumberTable:136. line 15: 0137. line 16: 4138. line 17: 9139. line 18: 14140. LocalVariableTable:141. Start Length Slot Name Signature142. 0 15 0 this LDog143. 0 15 1 name Ljava/lang/String144. 0 15 2 age I145.146. //这里的 Args_size1,是因为是 static 方法,不会传进 this147. public static void getStaticValueint148. Code:149. Stack2 Locals2 Args_size1150. 0: iload_0151. 1: istore_1 //istore_1 其实是是有两部分组成,i 表示 int 类型 ,1 表示局部变量表中 index 为 1。
那合起来就是存储在局部变 量表中,index 为 1 的位置152. 2: getstatic 4 //Field
java/lang/System.out:L
java/io/PrintStream //引用常量池 4153. 5: iload_1154. 6: invokevirtual 5 //Method
java/io/PrintStream.p rintln:IV //引用常量池 5155. 9: return156. LineNumberTable:157. line 21: 0158. line 22: 2159. line 23: 9160. LocalVariableTable:161. Start Length Slot Name Signature162. 0 10 0 j I163. 2 8 1 i I164.165. public void getValueint166. Code:167. Stack2 Locals3 Args_size2168. 0: iload_1169. 1: istore_2170. 2: getstatic 4 //Field
java/lang/System.out:L
java/io/PrintStream171. 5: iload_2172. 6: invokevirtual 5 //Method
java/io/PrintStream.p rintln:IV173. 9: return174. LineNumberTable:175. line 26: 0176. line 27: 2177. line 28: 9178. LocalVariableTable:179. Start Length Slot Name Signature180. 0 10 0 this LDog181. 0 10 1 j I182. 2 8 2 i I183. public static void mainjava.lang.String184. Code:185. Stack2 Locals2 Args_size1186. 0: new 6 //class Dog 解释:创建 Dog187. 3: dup //复制引用到 stack(栈)188. 4: invokespecial 7 //Method :V189. 7: bipush 10 //压入一个常量 10190. 9: invokevirtual 8 //Method getValue:IV191. 12: goto 20192. 15: astore_1193. 16: aload_1194. 17: invokevirtual 10 //Method
java/lang/Exception. printStackTrace:V195. 20: return196. Exception table:197. from to target type198. 0 12 15 Class
java/lang/Exception //表示上面 代码从 1 到 12 行之间如果发生 Exception 异常就 goto 到 15 处199. LineNumberTable:200. line 32: 0201. line 35: 12202. line 33: 15203. line 34: 16204. line 36: 20205.206. LocalVariableTable:207. Start Length Slot Name Signature208. 0 21 0 args Ljava/lang/String209. 16 4 1 e Ljava/lang/Exception210.