前置++和后置++ 运算的详解及实例代码

 更新时间:2016年09月18日 14:42:34   投稿:lqh  
这篇文章主要介绍了前置++和后置++ 的相关资料,并附示例代码,帮助大家学习参考,需要的朋友可以参考下

一般认为前置++是先将变量的值加1,然后使用加1后的值参与运算;而后置++是先使用该值参与运算,然后再将该值加1。

先看第一个例子:

package test;
public class Plus_Test01 {
 public static void main(String[] args) {
  int i = 100;
  i = i++;
  System.out.println(i);
 }
}

猜猜结果是什么?

接着看第二个:

package test;
public class Plus_Test02 {
 public static void main(String[] args) {
  int k = 100;
  while (true) {
   if (k++ > 100) {
    // System.out.println(k);
    break;
   }
   System.out.println(k);
  }
 }
}

猜猜结果是什么?

实际上,不管是前置++,还是后置++,都是先将变量的值加1,然后才继续计算的。二者之间真正的区别是:前置++是将变量的值加1后,使用增值后的变量进行运算的,而后置++是首先将变量赋值给一个临时变量,接下来对变量的值加1,然后使用那个临时变量进行运算。

对于如下代码片段(前置++):

int i=1;
int j=++i*5;

实际第二句上相当于:

i+=1; //将i加1
j=i*5; //将加1后的值与之进行计算, 此结果为:10

而对于如下代码片段(后置++):

int i=1;
int j=i++*5;

第二句上相当于:

int temp=i;  // 将i赋值给一个临时变量
i+=1;        //将i加1
j=temp*5;   //将临时变量与之计算, 此结果为:5

对于第一个例子,相当于:

int temp=i;
i+=1;
i=temp; //

所以结果应该为不变的,即100。

第一个例子的汇编代码为:

 public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
  stack=2, locals=2, args_size=1
   0: bipush  100
   2: istore_1
   3: iload_1
   4: iinc   1, 1 //local var中第二个 加1
   7: istore_1    //保存至local var
   8: getstatic  #16     // Field java/lang/System.out:Ljava/io/PrintStream;
   11: iload_1 //加载的参数为栈中的第二个,即仍然为100
   12: invokevirtual #22     // Method java/io/PrintStream.println:(I)V
   15: return

对于第二个例子,其实不难,结果是101,注意看一下流程,以后不能在犯这样的错误了。(流程为:首先比较temp=i,temp>100,,显然不成立,将i+=1,跳到syso那一句,打印的当然是101,再次循环同样有temp=i,temp>100,这次是成立的,然后i+=1,直接跳出循环,不会执行while里面的语句)。

第二个例子的汇编(只选取了main方法):

 public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
  stack=2, locals=2, args_size=1
   0: bipush  100  //100压栈
   2: istore_1     //保存至第二个local var(第一个local var 是方法参数)
   3: iload_1     //从第二个local var加载
   4: iinc   1, 1  //给local var的2号位置的int值增加1(局部变量自增,结果仍然在local var中,操作数栈顶1不会变)
   7: bipush  100 //100压栈
   9: if_icmple  15 //比较操作数栈顶的两个int整型值,如果第一个小于或者等于第二个的话,然后跳转到15行
   12: goto   25 //否则跳转到25行(即操作数栈顶1>操作数栈顶2)
   15: getstatic  #2     // Field java/lang/System.out:Ljava/io/PrintStream;
   18: iload_1 // //从第一个个local var加载
   19: invokevirtual #3     // Method java/io/PrintStream.println:(I)V //调用该方法
   22: goto   3 //再次回跳至3,再次循环
   25: return //退出

第三个例子:

 package test;
 
 public class Plus_Test03 {
 
  static int proPlus() {
   int i = 55;
   int j = ++i;
   return j; //56
  }
 
  static int postPlus() {
   int i = 55;
   int j = i++;
   return j; //55
  }
 
  public static void main(String[] args) {
  System.out.println(proPlus());//56
   System.out.println(postPlus());//55
 
  }
}

第三个例子的汇编:

static int proPlus();
 descriptor: ()I
 flags: ACC_STATIC
 Code:
  stack=1, locals=2, args_size=0
   0: bipush  55 //55压栈
   2: istore_0   //将int型栈顶的存储至第一个local var
   3: iinc   0, 1 //第一个local var加1
   6: iload_0   //从local var加载
   7: istore_1  //保存至第二个local var
   8: iload_1   //栈顶为第二个local var
   9: ireturnstatic int postPlus();
 descriptor: ()I
 flags: ACC_STATIC
 Code:
  stack=1, locals=2, args_size=0
   0: bipush  55 
   2: istore_0
   3: iload_0    //加载至栈
   4: iinc   0, 1 //第一个local var加1
   7: istore_1
   8: iload_1
   9: ireturn

可见,前置++ 和后置++的不同点在于上面蓝色(//第一个local var加1)的部分,这两部分是反过来的。对于前置来说,会将local var中的数加1然后加载至栈中,而后置则是先从栈local var中加载至栈,然后将local var的加1,相当于留了一个备份。

结论:

一。前置、与后置++都是先将变量的值加1,而不是前置++先加1然后运算,而后置++先运算后加1。
二。从程序上说,后置++先将变量赋值给一个临时变量,然后将变量的值加1,接下来使用那个临时变量参与运算。
三。从指令上说,后置++在执行增值指令(iinc)前,先将变量的值压入栈,执行增值指令后,使用的是之前压入栈的值。

希望通过此文,彻底理解前置++和后置++的运算区别,谢谢大家对本站的支持!

相关文章

  • 源码解析JDK 1.8 中的 Map.merge()

    源码解析JDK 1.8 中的 Map.merge()

    这篇文章主要介绍了JDK 1.8 之 Map.merge()的相关知识,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • java实现点击按钮事件弹出子窗口

    java实现点击按钮事件弹出子窗口

    这篇文章主要为大家详细介绍了java实现点击按钮事件弹出子窗口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Spring中Bean对象的定义、注册和获取流程分析

    Spring中Bean对象的定义、注册和获取流程分析

    这篇文章主要介绍了Spring中Bean对象的定义、注册和获取流程分析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • IDEA运行SSM项目的超详细图解教程

    IDEA运行SSM项目的超详细图解教程

    SSM项目部署其实很简单,下面这篇文章主要给大家介绍了关于IDEA运行SSM项目的超详细图解教程,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • Java如何使用Agent和ASM在字节码层面实现方法拦截

    Java如何使用Agent和ASM在字节码层面实现方法拦截

    Agent是一种运行在 Java 虚拟机 (JVM) 上的特殊程序,ASM是一个轻量级的 Java 字节码编辑和分析框架,本文为大家介绍了如何利用他们在字节码层面实现方法拦截,感兴趣的可以了解一下
    2023-05-05
  • RabbitMQ简单队列实例及原理解析

    RabbitMQ简单队列实例及原理解析

    这篇文章主要介绍了RabbitMQ简单队列实例及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • List集合多线程并发条件下不安全如何解决

    List集合多线程并发条件下不安全如何解决

    List是我们常用的集合,但是在多线程并发的条件下,会出现安全问题吗?下面我们就来测试一下,如果出现安全问题,该如何解决,感兴趣的可以了解一下
    2021-12-12
  • java实现远程连接执行命令行与上传下载文件

    java实现远程连接执行命令行与上传下载文件

    这篇文章主要介绍了java实现远程连接执行命令行与上传下载文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • 关于JWT与cookie和token的区别说明

    关于JWT与cookie和token的区别说明

    这篇文章主要介绍了JWT与cookie和token的区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • java判断今天,昨天,前天,不能用秒间隔的简单实例

    java判断今天,昨天,前天,不能用秒间隔的简单实例

    下面小编就为大家带来一篇java判断今天,昨天,前天,不能用秒间隔的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03

最新评论