java 分析 i++ 和++i 区别

    i++和++i的区别?

//1号代码段
public class test02 {
	public static void main(String[] args) {
		int i=10;
		i++;
		int j=11;
		++j;
		
		
	}
}

使用javap查看字节码

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: istore_1
       3: iinc          1, 1
       6: bipush        11
       8: istore_2
       9: iinc          2, 1
      12: return
}

此时发现字节码执行顺序是一样的,

再看如下的代码

//2号代码段
public class test02 {
	public static void main(String[] args) {
		int i=10;
		System.out.println(i++);//10
		
		int j=11;
		System.out.println(++j);//12
		
		
	}
}

使用javap查看字节码

 public static void main(java.lang.String[]);
    Code:
       0: bipush        10                  值带符号扩展成int值入栈                          
       2: istore_1                          将栈顶int类型值保存到局部变量1中
       3: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
       6: iload_1                           从局部变量1中装载int类型值入栈
       7: iinc          1, 1                 局部变量1加1这个指令不会导致栈的变化
      10: invokevirtual #22                 // Method java/io/PrintStream.println:(I)V
      13: bipush        11                   值带符号扩展成int值入栈      
      15: istore_2                           将栈顶int类型值保存到局部变量2中
      16: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      19: iinc          2, 1                 局部变量2加1这个指令不会导致栈的变化
      22: iload_2                           从局部变量2中装载int类型值入栈
      23: invokevirtual #22                 // Method java/io/PrintStream.println:(I)V
      26: return
}

java 分析 i++ 和++i 区别_第1张图片

   注意红框的部分,很明显临时变量的中i++是先赋值后加1,++i是先加1再赋值

再看一段代码

public class test02 {
	public static void main(String[] args) {
		int i=10;
		i=i++;
		System.out.println(i);//10
		int j=11;
		j=++j;
		System.out.println(j);//12

	}
}

使用javap查看字节码

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10                   值带符号扩展成int值入栈    
       2: istore_1                           将栈顶int类型值保存到局部变量1中
       3: iload_1                             从局部变量1中装载int类型值入栈
       4: iinc          1, 1                  局部变量1加1这个指令不会导致栈的变化
       7: istore_1                            将栈顶int类型值保存到局部变量1中
       8: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: iload_1                             从局部变量1中装载int类型值入栈
      12: invokevirtual #22                 // Method java/io/PrintStream.println:(I)V
      15: bipush        11                       值带符号扩展成int值入栈  
      17: istore_2                            将栈顶int类型值保存到局部变量2中
      18: iinc          2, 1                  局部变量2加1这个指令不会导致栈的变化
      21: iload_2                             从局部变量2中装载int类型值入栈
      22: istore_2                             将栈顶int类型值保存到局部变量2中
      23: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      26: iload_2                             从局部变量2中装载int类型值入栈
      27: invokevirtual #22                 // Method java/io/PrintStream.println:(I)V
      30: return
}

java 分析 i++ 和++i 区别_第2张图片

注意红框部分, 因为i++和++j的底层操作的区别,栈顶int类型值的不一致,导致局部变量的值不一致,也就造成了最后输出的不一致。

   为什么直接输出i++会是0,i++之后输出i是1

public class test02 {
	public static void main(String[] args) {
		int j=10;
		System.out.println(j++);//10
		System.out.println("===========");
		int i=10;
		i++;
		System.out.println(i);//11
		
 }
}

字节码如下

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10                      值带符号扩展成int值入栈    
       2: istore_1                              将栈顶int类型值保存到局部变量1中
       3: getstatic     #16                    // Field java/lang/System.out:Ljava/io/PrintStream;
       6: iload_1                               从局部变量1中装载int类型值入栈
       7: iinc          1, 1                    局部变量1加1这个指令不会导致栈的变化
      10: invokevirtual #22                 // Method java/io/PrintStream.println:(I)V
      13: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      16: ldc           #28                 // String ===========
      18: invokevirtual #30                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      21: bipush        10                    值带符号扩展成int值入栈  
      23: istore_2                             将栈顶int类型值保存到局部变量2中  
      24: iinc          2, 1                    局部变量2加1这个指令不会导致栈的变化
      27: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
      30: iload_2                               从局部变量2中装载int类型值入栈
      31: invokevirtual #22                 // Method java/io/PrintStream.println:(I)V
      34: return
}

java 分析 i++ 和++i 区别_第3张图片

观察红框部分可以得知在运行i++的时候做了加1之后并没有值更新,在后半段代码中,输出i的时候是又会进行值更新,这就是原因.

你可能感兴趣的:(JAVA)