前面发了几篇学习笔记,但是看这些东西总是感觉很"玄乎",来一篇实战的东西来揭一下"JVM"的面纱,让"SSH"时代的童鞋们来熟悉一下Java的"老祖爷"JVM。由于自己的水平有限,所以大家在看过程中发了什么问题,或者您有什么疑问请及时提出来,我及时解决。如果您有什么建议,那么更好大家一块讨论。

1、源码文件

  1. public class LearningClassFile {
  2. //普通变量
  3. private int id1;
  4. //静态变量
  5. private static int id2;
  6. //常量
  7. private final int id3 = 4;
  8. //静态常量
  9. private static final int id4 = 5;
  10. public LearningClassFile() {
  11. }
  12. public LearningClassFile(int id1, int id2) {
  13. this.id1 = id1;
  14. this.id2 = id2;
  15. }
  16. //使用public修饰的addPub方法
  17. public void addPub(int a, int b) {
  18. int result = a + b;
  19. System.out.println(result);
  20. }
  21. //使用private修饰的addPri方法
  22. private void addPri(int a, int b) {
  23. int result = a + b;
  24. System.out.println(result);
  25. }
  26. //使用static修饰的方法
  27. public static void addSta() {
  28. int result = id2 + id4;
  29. System.out.println(result);
  30. }
  31. public static final void addFinal(int a, int b) {
  32. int result = a + b;
  33. System.out.println(result);
  34. }
  35. public static void main(String[] args) {
  36. LearningClassFile lcf = new LearningClassFile(1, 2);
  37. lcf.addPub(1, 2);
  38. lcf.addPri(1, 2);
  39. addSta();
  40. addFinal(1, 2);
  41. }
  42. }

Class文件:

  1. Compiled from "LearningClassFile.java"
  2. public class LearningClassFile extends java.lang.Object
  3. SourceFile: "LearningClassFile.java"
  4. minor version: 0
  5. major version: 50
  6. //运行时常量池:用于存放编译期生成的各种字面量和符号引用。
  7. Constant pool:
  8. //从父类Object继承的默认构造方法
  9. //观察该方法的特征:无参,返回类型void
  10. const #1 = Method       #13.#35;        //  java/lang/Object."<init>":()V
  11. //常量id3
  12. //"#7.#36; //  LearningClassFile.id3:I"
  13. //#7:查找常量池中的类名LearningClassFile
  14. //#36-->"const #36 = NameAndType #17:#15;//  id3:I"
  15. //NameAndType字面的意思是名称和类型。即id3是变量的名称,I表示id3是int类型
  16. //综合描述:LearningClassFile中的id3是int类型
  17. const #2 = Field        #7.#36; //  LearningClassFile.id3:I
  18. const #3 = Field        #7.#37; //  LearningClassFile.id1:I
  19. const #4 = Field        #7.#38; //  LearningClassFile.id2:I
  20. //将System的out存储至常量池
  21. //System类中out被public static final修饰的
  22. //"public final static PrintStream out = nullPrintStream();"
  23. //综合描述:System类的out属性是PrintStream类型
  24. const #5 = Field        #39.#40;        //  java/lang/System.out:Ljava/io/PrintS
  25. tream;
  26. //将PrintStream的Println()方法存储至常量池
  27. //该方法的参数为I,返回值为void
  28. const #6 = Method       #41.#42;        //  java/io/PrintStream.println:(I)V
  29. //类LearningClassFIle
  30. const #7 = class        #43;    //  LearningClassFile
  31. //构造函数
  32. //该构造函数需传入两个int类型的变量
  33. const #8 = Method       #7.#44; //  LearningClassFile."<init>":(II)V
  34. //LearningClassFile的addPub方法
  35. //#4-->"const #45 = NameAndType #27:#26;//  addPub:(II)V"
  36. //#27-->"const #27 = Asciz       addPub;"    方法的名称为:addPub
  37. //#26-->"const #26 = Asciz       (II)V;"     方法的类型:两个int类型的参数,返回类型为void
  38. const #9 = Method       #7.#45; //  LearningClassFile.addPub:(II)V
  39. const #10 = Method      #7.#46; //  LearningClassFile.addPri:(II)V
  40. const #11 = Method      #7.#47; //  LearningClassFile.addSta:()V
  41. const #12 = Method      #7.#48; //  LearningClassFile.addFinal:(II)V
  42. const #13 = class       #49;    //  java/lang/Object
  43. const #14 = Asciz       id1;
  44. const #15 = Asciz       I;
  45. const #16 = Asciz       id2;
  46. const #17 = Asciz       id3;
  47. //ConstantValue属性表示一个常量字段的值
  48. //即final修饰的属性
  49. const #18 = Asciz       ConstantValue;
  50. //对于final修饰的常量直接将类型和值存入常量池
  51. const #19 = int 4;
  52. const #20 = Asciz       id4;
  53. const #21 = int 5;
  54. const #22 = Asciz       <init>;
  55. const #23 = Asciz       ()V;
  56. //Code属性只为唯一一个方法、实例类初始化方法或类初始化方法保存Java虚拟机指令及相关辅助信息
  57. //简而言之:保存方法编译后的指令信息
  58. const #24 = Asciz       Code;
  59. //java源码行号与编译后的字节码指令的对应表
  60. const #25 = Asciz       LineNumberTable;
  61. const #26 = Asciz       (II)V;
  62. const #27 = Asciz       addPub;
  63. const #28 = Asciz       addPri;
  64. const #29 = Asciz       addSta;
  65. const #30 = Asciz       addFinal;
  66. const #31 = Asciz       main;
  67. const #32 = Asciz       ([Ljava/lang/String;)V;
  68. //java 源码文件
  69. const #33 = Asciz       SourceFile;
  70. const #34 = Asciz       LearningClassFile.java;
  71. const #35 = NameAndType #22:#23;//  "<init>":()V
  72. const #36 = NameAndType #17:#15;//  id3:I
  73. const #37 = NameAndType #14:#15;//  id1:I
  74. const #38 = NameAndType #16:#15;//  id2:I
  75. const #39 = class       #50;    //  java/lang/System
  76. const #40 = NameAndType #51:#52;//  out:Ljava/io/PrintStream;
  77. const #41 = class       #53;    //  java/io/PrintStream
  78. const #42 = NameAndType #54:#55;//  println:(I)V
  79. const #43 = Asciz       LearningClassFile;
  80. const #44 = NameAndType #22:#26;//  "<init>":(II)V
  81. const #45 = NameAndType #27:#26;//  addPub:(II)V
  82. const #46 = NameAndType #28:#26;//  addPri:(II)V
  83. const #47 = NameAndType #29:#23;//  addSta:()V
  84. const #48 = NameAndType #30:#26;//  addFinal:(II)V
  85. const #49 = Asciz       java/lang/Object;
  86. const #50 = Asciz       java/lang/System;
  87. const #51 = Asciz       out;
  88. const #52 = Asciz       Ljava/io/PrintStream;;
  89. const #53 = Asciz       java/io/PrintStream;
  90. const #54 = Asciz       println;
  91. const #55 = Asciz       (I)V;
  92. {
  93. //默认构造方法
  94. public LearningClassFile();
  95. Code:
  96. Stack=2, Locals=1, Args_size=1
  97. 0:   aload_0
  98. 1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
  99. //将id3的引用推送至栈顶
  100. 4:   aload_0
  101. //将4推送至栈顶
  102. 5:   iconst_4
  103. //将4赋值给id3
  104. 6:   putfield        #2; //Field id3:I
  105. 9:   return
  106. LineNumberTable:
  107. line 11: 0   //public LearningClassFile() {
  108. //对于final类型的实例变量在每个构造方法中都会进行一次初始化。
  109. line 7: 4    //    private final int id3 = 4;
  110. line 12: 9   //}
  111. public LearningClassFile(int, int);
  112. Code:
  113. Stack=2, Locals=3, Args_size=3
  114. 0:   aload_0
  115. 1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
  116. 4:   aload_0
  117. 5:   iconst_4
  118. 6:   putfield        #2; //Field id3:I
  119. 9:   aload_0
  120. 10:  iload_1
  121. 11:  putfield        #3; //Field id1:I
  122. 14:  aload_0
  123. 15:  pop
  124. 16:  iload_2
  125. 17:  putstatic       #4; //Field id2:I
  126. 20:  return
  127. LineNumberTable:
  128. line 14: 0    //public LearningClassFile(int id1, int id2) {
  129. //对于final类型的实例变量在每个构造方法中都会进行一次初始化。
  130. line 7: 4     //    private final int id3 = 4;
  131. line 15: 9    //    this.id1 = id1;
  132. line 16: 14   //    this.id2 = id2;
  133. line 17: 20   //}
  134. public void addPub(int, int);
  135. Code:
  136. Stack=2, Locals=4, Args_size=3
  137. 0:   iload_1
  138. 1:   iload_2
  139. 2:   iadd
  140. 3:   istore_3
  141. 4:   getstatic       #5; //Field java/lang/System.out:Ljava/io/PrintStream;
  142. 7:   iload_3
  143. 8:   invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
  144. 11:  return
  145. LineNumberTable:
  146. line 21: 0    //    int result = a + b;
  147. line 22: 4    //    System.out.println(result);
  148. line 23: 11   // }
  149. public static void addSta();
  150. Code:
  151. Stack=2, Locals=1, Args_size=0
  152. //获取静态变量id2推送至栈顶
  153. 0:   getstatic       #4; //Field id2:I
  154. //直接从常量池中取出id4的值5推送至栈顶
  155. 3:   iconst_5
  156. //执行相加操作
  157. 4:   iadd
  158. //将计算结果推送至栈顶
  159. 5:   istore_0
  160. //获取静态与out
  161. 6:   getstatic       #5; //Field java/lang/System.out:Ljava/io/PrintStream;
  162. //取出计算结果
  163. 9:   iload_0
  164. //调用println方法
  165. 10:  invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
  166. //方法正常结束
  167. 13:  return
  168. LineNumberTable:
  169. line 33: 0    //     int result = id2 + id4;
  170. line 34: 6    //     System.out.println(result);
  171. line 35: 13   //}
  172. public static final void addFinal(int, int);
  173. Code:
  174. Stack=2, Locals=3, Args_size=2
  175. 0:   iload_0
  176. 1:   iload_1
  177. 2:   iadd
  178. 3:   istore_2
  179. 4:   getstatic       #5; //Field java/lang/System.out:Ljava/io/PrintStream;
  180. 7:   iload_2
  181. 8:   invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
  182. 11:  return
  183. LineNumberTable:
  184. line 38: 0
  185. line 39: 4
  186. line 40: 11
  187. public static void main(java.lang.String[]);
  188. Code:
  189. Stack=4, Locals=2, Args_size=1
  190. //创建一个LearningClassFile对象,并将对象的引用推送至栈顶
  191. 0:   new     #7; //class LearningClassFile
  192. //将对象的引用进行备份推送至栈顶
  193. //使用原有的引用值调用实例方法,现在置于栈顶的引用值的位置将被接下来的操作覆盖。
  194. 3:   dup
  195. //将构造函数中的参数1推送至栈顶
  196. 4:   iconst_1
  197. 5:   iconst_2
  198. //执行构造方法
  199. 6:   invokespecial   #8; //Method "<init>":(II)V
  200. //将栈顶引用型数值存入第二个本地变量
  201. 9:   astore_1
  202. 10:  aload_1
  203. 11:  iconst_1
  204. 12:  iconst_2
  205. //调用实例方法
  206. 13:  invokevirtual   #9; //Method addPub:(II)V
  207. 16:  aload_1
  208. 17:  iconst_1
  209. 18:  iconst_2
  210. 19:  invokespecial   #10; //Method addPri:(II)V
  211. //调用静态方法
  212. 22:  invokestatic    #11; //Method addSta:()V
  213. 25:  iconst_1
  214. 26:  iconst_2
  215. 27:  invokestatic    #12; //Method addFinal:(II)V
  216. 30:  return
  217. LineNumberTable:
  218. line 43: 0     //   LearningClassFile lcf = new LearningClassFile(1, 2);
  219. line 44: 10    //   lcf.addPub(1, 2);
  220. line 45: 16    //   lcf.addPri(1, 2);
  221. line 46: 22    //   addSta();
  222. line 47: 25    //   addFinal(1, 2);
  223. line 48: 30    //}
  224. }

final变量和static final变量的区别:

(1)实例常量和类常量的区别

(2)初识方式不同:从class字节码来看final修饰的变量会出现在每个构造方法中进行一次初始化;static final类型的变量必须在定义的时候进行初始化。 理解"编译期可知,运行期不变": 编译器可确定调用方法的版本,符合这个标准的方法主要有两种:私有方法,静态方法。

详情请看:深入理解JVM读书笔记--字节码执行引擎。

2、final变量和static final变量的区别:

(1)实例常量和类常量的区别

(2)初始化方式不同:从class字节码来看final修饰的变量会出现在每个构造方法中进行一次初始化;static final类型的变量必须在定义的时候进行初始化。

3、理解"编译期可知,运行期不变":

编译器可确定调用方法的版本,符合这个标准的方法主要有两种:私有方法,静态方法。

深入Java虚拟机:Class文件实例解析相关推荐

  1. POI以SAX方式解析Excel2007大文件(包含空单元格的处理) Java生成CSV文件实例详解...

    http://blog.csdn.net/l081307114/article/details/46009015 http://www.cnblogs.com/dreammyle/p/5458280. ...

  2. 什么是java内省_Java内省实例解析

    图像中轮廓的个数,里面vector的size代表了轮廓上点的个数.了解JavaBean 内省对应的英文单词为IntroSpector,它主要用于对JavaBean进行操作,JavaBean是一种特殊的 ...

  3. List元素互换,List元素转换下标,Java Collections.swap()方法实例解析

    Java Collections.swap()方法解析 jdk源码: public static void swap(List<?> list, int i, int j) {// ins ...

  4. java虚拟机编译文件,理解Java虚拟机(1)之一个.java文件编译成.class文件发生了什么...

    理解Java虚拟机(1)之一个.java文件编译成.class文件发生了什么 最近在看<深入理解Java虚拟机>弄明白了很多java的底层知识,决定分几部分总结下,从.java文件编译,到 ...

  5. java hasnext_java hasNext()使用实例解析

    这篇文章主要介绍了java hasNext()使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 编写一段程序实现如果输入的一组数中含非整数 ...

  6. java斗地主代码_实例解析java如何实现斗地主代码

    实例解析java如何实现斗地主代码 发布时间:2020-07-20 14:41:41 来源:亿速云 阅读:73 作者:小猪 小编这次要给大家分享的是实例解析java如何实现斗地主代码,文章内容丰富,感 ...

  7. Java 虚拟机枚举 GC Roots 解析

    原始链接:https://www.leahy.club/archives/gcroots 最近在复习JVM,在看<深入理解Java虚拟机>中关于GC Roots的描述不是很明白,就收集了相 ...

  8. 如何调优JVM - 优化Java虚拟机(大全+实例)

    堆设置 -Xmx3550m:设置JVM最大堆内存 为3550M. -Xms3550m:设置JVM初始堆内存 为3550M.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存. -X ...

  9. Java的clone()用法实例解析

    1.背景 用java写程序的时候很苦恼的一件事就是,如果将一个对象a赋给另一个对象b,那么你改变a的变量值得时候,b的值也对应的变化.如果我们只想单纯的获取那个时刻的a的状况给b的话,就要用到clon ...

最新文章

  1. android中AVD的使用
  2. 正在安装虚拟网络驱动程序卡住了_如何在Hyper-V、Virtual PC等虚拟机中使用USB设备...
  3. php伪静态url运用,再谈 THINKPHP 伪静态url(URL访问模式)的设置
  4. oracle1461,Oracle 10.2.0.3的ORA-1461错误
  5. 【Swift学习】Swift编程之旅(一)
  6. 解密 Go interface 的类型转换原理
  7. hadoop框架分析
  8. WebRequestDataBinder实现将请求参数映射为POJO对象
  9. 简单的用堆栈实现的表达式计算
  10. Confluence 6 SQL Server 数据库驱动修改
  11. oracle+性能负载查看,Oracle 11g数据库重放教程(二):负载重放基本实例讲解-性能调优-Oracle频道-中国IT实验室...
  12. 最著名的数学家一般也是最著名的力学家
  13. MinGW安装及介绍
  14. vue运行报错冒号问题,browser.js:158 Uncaught SyntaxError: Unexpected token ‘:‘
  15. android 面包屑控件,android面包屑導航欄的實現
  16. 宝宝专业智力测试软件,儿童医院心理科做智商检测-儿童智力测试仪_儿童注意力测试仪_儿童综合素质测试仪/测评系统...
  17. 光猫下连接路由器的详细步骤
  18. 系统等保指的是信息系统的安全保护等级
  19. (附源码)springboot校园兼职系统 毕业设计 031122
  20. [SQLite 开发] 移除掉一个字串中的字头或字尾空格(TRIM)

热门文章

  1. 【Android 组件化】路由组件 ( 生成 Root 类记录模块中的路由表 )
  2. 【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )
  3. 流程图软件draw.io
  4. PE知识复习之PE的两种状态
  5. 【leetcode】500. Keyboard Row
  6. Linux下TCP最大连接数受限问题
  7. Window CMD快捷键
  8. 洛谷P1546 最短网络 Agri-Net
  9. 将功补过 树形动态规划
  10. 软件开发人员该如何深入理解自己的代码