Java中的递增i++与++i的实现原理详解

 更新时间:2023年10月13日 10:42:42   作者:ゞ浪人与酒丶0  
这篇文章主要介绍了Java中的i++与++i的实现原理详解,在Java中,i++是一种常见的递增操作符,用于将变量i的值增加1,它是一种简洁且方便的方式来实现循环和计数功能,i++可以用于各种情况,本文来看一下其实现原理,需要的朋友可以参考下

前言

在Java中,i++是一种常见的递增操作符,用于将变量i的值增加1。

它是一种简洁且方便的方式来实现循环和计数功能。i++可以用于各种情况,例如在for循环中迭代数组或列表的元素,或者在计数器中跟踪某个事件的发生次数。

通过使用i++,我们可以轻松地实现自增操作,而无需手动编写i = i + 1的代码。

i++

首先先看一段代码

public class Test {
    public static void main(String[] args) {
        foo();
    }
    public static void foo() {
       int i = 0;
        for (int j = 0; j < 50; j++) {
            i = i++;
        }
        System.out.println(i);
    }
}

执行上述代码输出结果是0,而不是50

0

对应字节码

public class com.yxzapp.Test {
  public com.yxzapp.Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #2                  // Method foo:()V
       3: return
  public static void foo();
    Code:
       0: iconst_0
       1: istore_0
       2: iconst_0
       3: istore_1
       4: iload_1
       5: bipush        50
       7: if_icmpge     21
      10: iload_0                           // 把局部变量下标0的变量加载到操作数栈上
      11: iinc          0, 1                // 对局部变量表表为0的int变量直接加1,但是这												个时候栈顶元素没有变化,还是0
      14: istore_0 							// 将栈顶元素出栈赋值给局部变量下标0变量 也就												是i。 此时 局部变量 i 又被赋值为0,前面 iinc  											指令对i 的加一操作一样被覆盖
      15: iinc          1, 1
      18: goto          4
      21: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      24: iload_0
      25: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
      28: return
}

image.png

在字节码层面是先把 i 加载到操作数栈上,随后才对局部变量 i 执行加一操作 , 留在操作数栈顶的还是 i 的旧值。则这个变量得到的是 i 加一之前的值

++i

public class Test {
    public static void main(String[] args) {
        foo();
    }
    public static void foo() {
       int i = 0;
        for (int j = 0; j < 50; j++) {
            i = ++i;
        }
        System.out.println(i);
    }
}

对应字节码

public class com.yxzapp.Test {
  public com.yxzapp.Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #2                  // Method foo:()V
       3: return
  public static void foo();
    Code:
       0: iconst_0
       1: istore_0
       2: iconst_0
       3: istore_1
       4: iload_1
       5: bipush        50
       7: if_icmpge     21
      10: iinc          0, 1                // 对局部变量表表为0的int变量直接加1,
      13: iload_0                           // 把局部变量下标0的变量加载到操作数栈上
      14: istore_0                          // 将栈顶元素出栈赋值给局部变量下标0变量
      15: iinc          1, 1
      18: goto          4
      21: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      24: iload_0
      25: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
      28: return
}

可以看出 i= ++i , 先对局部变量表下标为0的变量加 1 ,然后才把它加载到操作数栈上,随后又从操作数栈上出栈赋值给局部变量表中下标为 0 的变量

image.png

总结 

  • i++ 即后加加,原理是:先自增,然后返回自增之前的值、
  • ++i 即前加加,原理是:先自增,然后返回自增之后的值

到此这篇关于Java中的递增i++与++i的实现原理详解的文章就介绍到这了,更多相关i++与++i的实现原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring WebMVC初始化Controller流程详解

    Spring WebMVC初始化Controller流程详解

    这篇文章主要介绍了Spring WebMVC初始化Controller流程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • java实现客房管理系统

    java实现客房管理系统

    这篇文章主要为大家详细介绍了java实现客房管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • idea中断点类型之All和Thread的区别介绍

    idea中断点类型之All和Thread的区别介绍

    使用all模式对于程序中含有多个线程来说,会将多个线程都阻塞在断点,此时所有的线程都执行到此处,在最后一个线程执行到此处是会发生暂停,在这之前的线程会继续执行到任意位置,本文给大家详细介绍下idea中断点类型之All和Thread的区别,感兴趣的朋友一起看看吧
    2022-03-03
  • java实现大数加法(BigDecimal)的实例代码

    java实现大数加法(BigDecimal)的实例代码

    之前写过用vector、string实现大数加法,现在用java的BigDecimal类,代码简单很多。但是在online-judge上,java的代码运行时间和内存大得多
    2013-10-10
  • Springboot实现动态定时任务流程详解

    Springboot实现动态定时任务流程详解

    通过重写SchedulingConfigurer方法实现对定时任务的操作,单次执行、停止、启动三个主要的基本功能,动态的从数据库中获取配置的定时任务cron信息,通过反射的方式灵活定位到具体的类与方法中
    2022-09-09
  • Spring JdbcTemplate实现添加与查询方法详解

    Spring JdbcTemplate实现添加与查询方法详解

    JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下
    2022-11-11
  • Nacos配置的多文件加载与共享配置方式

    Nacos配置的多文件加载与共享配置方式

    这篇文章主要介绍了Nacos配置的多文件加载与共享配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 详解用java描述矩阵求逆的算法

    详解用java描述矩阵求逆的算法

    这篇文章主要介绍了用java描述矩阵求逆的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • spring cloud config和bus组件实现自动刷新功能

    spring cloud config和bus组件实现自动刷新功能

    今天通过本文给大家介绍spring cloud config和bus组件实现自动刷新功能,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-10-10
  • Java中的logback标记日志过滤器MarkerFilter详解

    Java中的logback标记日志过滤器MarkerFilter详解

    这篇文章主要介绍了Java中的logback标记日志过滤器MarkerFilter详解,在logback-classic中存在一个全局过滤器TurboFilter,TurboFilter是与LoggerContext绑定,会在会在其它过滤器之前执行,需要的朋友可以参考下
    2023-11-11

最新评论