Java中的递增i++与++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 }
在字节码层面是先把 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 的变量
总结
- i++ 即后加加,原理是:先自增,然后返回自增之前的值、
- ++i 即前加加,原理是:先自增,然后返回自增之后的值
到此这篇关于Java中的递增i++与++i的实现原理详解的文章就介绍到这了,更多相关i++与++i的实现原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Spring WebMVC初始化Controller流程详解
这篇文章主要介绍了Spring WebMVC初始化Controller流程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-02-02Spring JdbcTemplate实现添加与查询方法详解
JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下2022-11-11spring cloud config和bus组件实现自动刷新功能
今天通过本文给大家介绍spring cloud config和bus组件实现自动刷新功能,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧2021-10-10Java中的logback标记日志过滤器MarkerFilter详解
这篇文章主要介绍了Java中的logback标记日志过滤器MarkerFilter详解,在logback-classic中存在一个全局过滤器TurboFilter,TurboFilter是与LoggerContext绑定,会在会在其它过滤器之前执行,需要的朋友可以参考下2023-11-11
最新评论