自增(++)和自减(--)运算符

     自增(++):将变量的值加1,分前缀式(如++i)和后缀式(如i++)。前缀式是先加1再使用;后缀式是先使用再加1。
     自减(--):将变量的值减1,分前缀式(如--i)和后缀式(如i--)。前缀式是先减1再使用;后缀式是先使用再减1。

     我们先从问题入手:

int i = 0;
int j = i++;
int k = --i;
代码运行后,i等于多少?j等于多少?k等于多少? 
 结果:

分析结果:int j=i++;是后缀式,因此i的值先被赋予j,然后再自增1,所以这行代码运行后,i=1、j=0;而int k=--i;是前缀式,因此i先自减1,然后再将它的值赋予k,因此这行代码运行后,i=0、k=0。 

int i = 0;
int j = i++ + ++i;    //相当于0 + 2
int k = --i + i--;    //相当于1 + 1

代码运行后,i等于多少?j等于多少?k等于多少? 

结果:

 分析结果:对于int j=i++ + ++i;,首先运行i++,i的值0被用于加运算(+),之后i自增值变为1,然后运行++i,i先自增变为2,之后被用于加运算,最后将i两次的值相加的结果0+2=2赋给j,因此这行代码运行完毕后i=2、j=2;对于int k=--i + i--;用一样的思路分析,具体过程在此不再赘述,结果应该是i=0、k=2。

       

        为什么会有这样的结果呢?我们来看看++i和i++的字节码有什么不一样

        代码如下:

public class MyDemo {
    public static void main(String[] args) {
        beforeAdd(1);
        afterAdd(1);
    }
    public static void beforeAdd(int arg){
       int before = ++arg;
    }
    public static void afterAdd(int arg){
       int after =  arg++;
    }
}

 

         查看字节码指令:javap -v   路径MyDemo.class,得到如下字节码指令

 

      

             从上图分析:++i是先把自增再压栈,而i++是先压栈再自增,很明显解释上面例子的结果

             思考一个问题fori循环i++和++i的效率有差别吗?

             把上面的代码稍微修改:

public class MyDemo {
    public static void main(String[] args) {
        beforeAdd(1);
        afterAdd(1);
    }
    public static void beforeAdd(int arg){
        for (int i = 0; i < arg; ++i) {

        }
    }
    public static void afterAdd(int arg){
        for (int i = 0; i < arg; i++) {

        }
    }
}

      同样查看字节码指令:

      

      

      它们的字节码指令一样,所以它们的执行效率也一样。    

     自增与自减运算符其实还遵循以下规律:
     1. 可以用于整数类型byte、short、int、long,浮点类型float、double,以及字符串类型char。
     2. 在Java5.0及以上版本中,它们可以用于基本类型对应的包装器类Byte、Short、Integer、Long、Float、Double、Character。
     3. 它们的运算结果的类型与被运算的变量的类型相同。
 
    参考:《JAVA解惑系列》
原文地址:https://www.cnblogs.com/dyg0826/p/11226040.html