一直在学习Java,碰到了很多问题,碰到了很多关于i++和++i的难题,以及最经典的String str = "abc" 共创建了几个对象的疑难杂症。 知道有一日知道了java的反汇编 命令  javap。现将学习记录做一小结,以供自己以后翻看。如果有错误的地方,请指正

1.javap是什么:

where options include:

-c Disassemble the code

-classpath Specify where to find user class files

-extdirs Override location of installed extensions

-help Print this usage message

-J Pass directly to the runtime system

-l Print line number and local variable tables

-public Show only public classes and members

-protected Show protected/public classes and members

-package Show package/protected/public classes

and members (default)

-private Show all classes and members

-s Print internal type signatures

-bootclasspath Override location of class files loaded

by the bootstrap class loader

-verbose Print stack size, number of locals and args for met

hods

If verifying, print reasons for failure

以上为百度百科里对它的描述,只是介绍了javap的一些参数和使用方法,而我们要用的就是这一个:-c Disassemble the code。

明确一个问题:javap是什么? 网上有人称之为 反汇编器,可以查看java编译器为我们生成的字节码。通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。

2.初步认识javap

从一个最简单的例子开始:

这个例子中,我们只是简单的声明了两个int型变量并赋上初值。下面我们看看javap给我们带来了什么:(当然执行javap命令前,你得首先配置好自己的环境,能用javac编译通过了,即:javac TestJavap.java )

我们只看(方便起见,将注释写到每句后面)

Code:

0:   iconst_2     //把2放到栈顶 1:   istore_1     //把栈顶的值放到局部变量1中,即i中 2:   iconst_3    //把3放到栈顶 3:   istore_2     //把栈顶的值放到局部变量1中,即j中 4:   return

是不是很简单?(当然,估计需要点数据结构的知识) ,那我们就补点java的关于堆栈的知识:

对于 int i = 2;首先它会在栈中创建一个变量为i的引用,然后查找有没有字面值为2的地址,没找到,就开辟一个存放2这个字面值的地址,然后将i指向2的地址。

看了这段话,再比较下上面的注释,是不是完全吻合?

为了验证上面这一说法,我们继续实验:

我们将 i 和 j的值都设为2。按照以上理论,在声明j的时候,会去栈中招有没有字面值为2的地址,由于在栈中已经有2这个字面值,便将j直接指向2的地址。这样,就出现了i与j同时均指向2的情况。

拿出javap -c进行反编译:结果如下:

Code:

0:   iconst_2    //把2放到栈顶

1:   istore_1    //把栈顶的值放到局部变量1中,即i中

2:   iconst_2    //把2放到栈顶

3:   istore_2    //把栈顶的值放到局部变量2中,即j中(i 和 j同时指向2)

4:   return

虽然这里说i和j同时指向2,但这里不等于说i和j指向同一块地址(java是不允许程序员直接修改堆栈中的数据的,所以就不要想着,我是不是可以 修改栈中的2,那样岂不是i和j的值都会变化。另:在编译器内部,遇到j=2;时,它就会重新搜索栈中是否有2的字面值,如果没有,重新开辟地址存放2的 值;如果已经有了,则直接将j指向这个地址。因此,就算j另被赋值为其他值,如j=4,j值的改变不会影响到i的值。)

再来一个例子:

还是javap -c

Code:

0:   iconst_2    //把2放到栈顶

1:   istore_1    //把栈顶的值放到局部变量1中,即i中

2:   iload_1     // 把i的值放到栈顶,也就是说此时栈顶的值是2

3:   istore_2    //把栈顶的值放到局部变量2中,即j中

4:   return

看到这里是不是有点明确了?

既然我们对javap有了一定的了解,那我们就开始用它来解决一些实际的问题:

1.i++和++i的问题

反编译结果为

Code:

0:   iconst_1

1:   istore_1

2:   iinc    1, 1 //这个个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,i此时变成2了   5:   iconst_1

6:   istore_2

7:   iinc    2, 1//这个个指令,把局部变量2,也就是j,增加1,这个指令不会导致栈的变化,j此时变成2了

10:  return

可以看出,++在前在后,在这段代码中,没有任何不同。

我们再看另一段代码:

反编译结果:

Code:

0:   iconst_1

1:   istore_1

2:   iload_1

3:   iinc    1, 1  //局部变量1(即i)加1变为2,注意这时栈中仍然是1,没有改变

6:   istore_1    //把栈顶的值放到局部变量1中,即i这时候由2变成了1

7:   iconst_1

8:   istore_2

9:   iinc    2, 1 //局部变量2(即j)加1变为2,注意这时栈中仍然是1,没有改变

12:  iload_2    //把局部变量2(即j)的值放到栈顶,此时栈顶的值变为2

13:  istore_2   //把栈顶的值放到局部变量2中,即j这时候真正由1变成了2

14:  return

是否看明白了? 如果这个看明白了,那么下面的一个问题应该就是迎刃而解了:

m = m ++;这句话,java虚拟机执行时是这样的: m的值加了1,但这是栈中的值还是0, 马上栈中的值覆盖了m,即m变成0,因此不管循环多少次,m都等于0。

如果改为m = ++m; 程序运行结果就是100了。。。

java和c的反汇编_JAVAP -C反汇编指令的学习(转载)相关推荐

  1. C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...

  2. c语言反汇编工具,PVDasm 反汇编工具

    Proview (a.k.a PVDasm) Disassembler, 唯冠 (又名 PVDasm) 反汇编器,PVDasm 是自由. 互动. 适用于多种 CPU (英特尔 80 x 86 / Ch ...

  3. Java虚拟机必学之四大知识要点,附学习资料

    转载自  Java虚拟机必学之四大知识要点,附学习资料 作为一位 Java 程序员,在尽情享受 Java 虚拟机带来好处的同时,我们还应该去了解和思考"这些技术特性是如何实现的", ...

  4. 转行学习java自学好还是去培训学校学习好?系统学习路线推荐

    一:盲目的去学  当初我在对于java这个行业什么都不了解的情况下,比如:不知道未来发展趋势,不知道学习java应该注意哪些初始问题,不知道具体的学习规划学习路线等等,一味的买书看书,看视频,到了中期 ...

  5. Java 基础 第3阶段:高级应用——尚硅谷学习笔记(含面试题) 2023年

    Java 基础 第 3 阶段:高级应用--尚硅谷学习笔记(含面试题) 2023 年 Java 基础 第 3 阶段:高级应用--尚硅谷学习笔记(含面试题) 2023 年 第 9 章 异常处理 9.1 异 ...

  6. 《Java程序设计与数据结构教程(第二版)》学习指导

    <Java程序设计与数据结构教程(第二版)>学习指导 目录 图书简况 学习指导 第一章 绪论 第二章 数据和表达式 第三章 使用类和对象 第四章 条件和循环 第五章 编写类 第六章 图形用 ...

  7. 编程,C语言,代码,黑客,软件,JAVA,DW,软件设计等等,怎么循序渐进学习?

    目录 1. 编程 2.代码 3. 软件 4.C语言,JAVA 5.黑客 6. DW 7.总结 有同学在评论区里问我技术方向和发展前景的问题,虽然认真回答了一下,但我的专业毕竟不是那个方向的,只能说了解 ...

  8. 500+门java,python,js等常用语言入门,学习,实战,项目资料领取

    500+门java,python,js等常用语言入门,学习,实战,项目资料,提升自己

  9. java字节码反编译_javap 反编译 java 字节码文件

    概述: javap是 Java class文件分解器,可以反编译,也可以查看java编译器生成的字节码,从而对代码内部的执行逻辑进行分析. 语法: 把java文件编译为class文件:javac  T ...

最新文章

  1. Python测试框架pytest(02)PyCharm设置运行pytest、pytest.main()
  2. sqlalchemy根据表名动态创建model类
  3. char类型的实参与const char类型的形参不兼容_C++干货系列——顶层const和底层const...
  4. HDU 4282 A very hard mathematic problem 二分题目
  5. classpath和读取resources目录下的文件
  6. C++何时调用拷贝(复制)构造函数
  7. php清空dns缓存文件,dns清空-windows刷新本地DNS缓存的几种方法
  8. Java_cpu飙升排查
  9. 拉普拉斯方程与复微分
  10. java zip 文件夹_Java Zip文件文件夹示例
  11. R数据分析:用lme4包拟合线性和非线性混合效应模型
  12. python大数据是什么_python和大数据有什么关系?
  13. SCM-PEG2000-Maleimide,Mal-PEG2000-Succinimidyl Carboxymethyl Ester
  14. 【2004-3】【平分核桃】
  15. 读《你的知识需要管理》(整理)
  16. 最快速的OpenCV安装教程
  17. 部署filebeat收集nginx日志
  18. Lightdm Ubuntu轻量级桌面显示管理器配置
  19. 《道德经》第三十三章
  20. Stream Api详解

热门文章

  1. 【算法】剑指 Offer 35. 复杂链表的复制 【重刷】
  2. 【Elasticsearch】如何构建一个好的电商搜索引擎?
  3. 【FLink】cannot assign instance LinkedMap FlinkKafkaConsumerBase.pendingOffsetsToCommit
  4. 【ElasticSearch】Es 源码之 SearchTransportService 源码解读
  5. 【elasticsearch】 document 查询原理
  6. 【Kafka】kafka Java api 获取 kafka topic 或者 partition 占用的磁盘大小
  7. 60-127-040-源码-connector-Flink 1.9.0 with Hive
  8. 03-neo4j的命令
  9. 【Docker】Docker 启用 Kubernetes 报错 insecure-registries Must be host[ port] or CIDR
  10. kudu :impala 和 kuduClient 的选择