jvm自增,自减运行原理

简介: 在jvm中,涉及到变量运算时,会发生压栈弹栈等动作,但如果仅仅是自增和自减,那么jvm会直接在本地变量中实现。public class JavaTest{ public static void main(String[] args){ int ...

在jvm中,涉及到变量运算时,会发生压栈弹栈等动作,但如果仅仅是自增和自减,那么jvm会直接在本地变量中实现。

public class JavaTest{

    public static void main(String[] args){
        int a=1,b=1,c=1,d=1;
        a++;
        ++b;
        c = c++;
        d=++d;
        System.out.println(a+"..."+b+"..."+c+"..."+d);
    }
}

这段代码很简单,运行结果为2,2,1,2。
对于这样的结果大家可能都觉得是对的,因为c=c++的时候会先执行赋值操作,再进行自增,所以c等于1。但是c进行赋值之后,自增的操作也是c本身,为什么c这个变量不等于自增后的数值呢?
我们使用javap来将这段代码进行解析,结果如下:

F:\>javap -c JavaTest
Compiled from "JavaTest.java"
public class JavaTest {
  public JavaTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_1
       3: istore_2
       4: iconst_1
       5: istore_3
       6: iconst_1
       7: istore        4
       9: iinc          1, 1
      12: iinc          2, 1
      15: iload_3
      16: iinc          3, 1
      19: istore_3
      20: iinc          4, 1
      23: iload         4
      25: istore        4
      27: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      30: new           #3                  // class java/lang/StringBuilder
      33: dup
      34: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      37: iload_1
      38: invokevirtual #5                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      41: ldc           #6                  // String ...
      43: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      46: iload_2
      47: invokevirtual #5                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      50: ldc           #6                  // String ...
      52: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      55: iload_3
      56: invokevirtual #5                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      59: ldc           #6                  // String ...
      61: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      64: iload         4
      66: invokevirtual #5                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      69: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      72: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      75: return
}

下面我们来分析一下,前面0-7可以看出是定义了4个变量,分别进行压栈和弹栈操作,将变量最终放入到本地变量中。9这个操作就对应于代码中的a++,可以看出没有进行压栈和弹栈,只是执行了iinc,也就是自增操作,所以这个时候,本地变量中a就等于2。12对应于代码中的++b,情况和9类似。c=c++对应于15-19,从这里可以看出,jvm先执行了压栈,将c压入栈顶,然后执行自增操作,所以这个时候,栈顶的c为1,本地变量c为2,但是在这个时候,19又将栈顶的c弹栈并赋值给本地变量c了,所以本地变量c最终为1。d=++d和上面原理是一致的。
通过对代码的汇编码的分析,我们可以知道c=c++为什么等于自增前的c了,其实不是因为先进行了赋值,自增后的数据没有再次赋值,而是由于自增后被原数据给覆盖了。

目录
相关文章
|
2月前
|
自然语言处理 前端开发 Java
深入浅出JVM(六)之前端编译过程与语法糖原理
深入浅出JVM(六)之前端编译过程与语法糖原理
|
2月前
|
存储 缓存 算法
深入浅出JVM(二)之运行时数据区和内存溢出异常
深入浅出JVM(二)之运行时数据区和内存溢出异常
|
3天前
|
存储 监控 安全
深入理解Java虚拟机(JVM)原理
深入理解Java虚拟机(JVM)原理
|
9天前
|
Java 编译器
Java健壮性 Java可移植性 JDK, JRE, JVM三者关系 Java的加载与执行原理 javac编译与JAVA_HOME环境变量介绍 Java中的注释与缩进 main方法的args参数
Java健壮性 Java可移植性 JDK, JRE, JVM三者关系 Java的加载与执行原理 javac编译与JAVA_HOME环境变量介绍 Java中的注释与缩进 main方法的args参数
10 1
|
2月前
|
监控 Java 测试技术
滚雪球学Java(45):探秘Java Runtime类:深入了解JVM运行时环境
【5月更文挑战第20天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
22 1
滚雪球学Java(45):探秘Java Runtime类:深入了解JVM运行时环境
|
19天前
|
算法 Java
Java垃圾回收(Garbage Collection,GC)是Java虚拟机(JVM)的一种自动内存管理机制,用于在运行时自动回收不再使用的对象所占的内存空间
【6月更文挑战第18天】Java的GC自动回收内存,包括标记清除(产生碎片)、复制(效率低)、标记整理(兼顾连续性与效率)和分代收集(区分新生代和老年代,用不同算法优化)等策略。现代JVM通常采用分代收集,以平衡性能和内存利用率。
41 3
|
2天前
|
存储 监控 安全
深入理解Java虚拟机(JVM)原理
深入理解Java虚拟机(JVM)原理
|
25天前
|
存储 缓存 安全
JVM(三)-运行时数据区(栈、程序计数器)
JVM(三)-运行时数据区(栈、程序计数器)
15 2
|
9天前
|
存储 监控 算法
深入理解Java虚拟机(JVM)原理与调优技巧
深入理解Java虚拟机(JVM)原理与调优技巧
|
9天前
|
存储 缓存 监控
JVM中G1垃圾收集器:原理、过程和参数配置深入解析
JVM中G1垃圾收集器:原理、过程和参数配置深入解析