i++ 和 ++i 的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21586317/article/details/81710826

一、问题一:执行如下代码,将会输出什么?

1.代码:

public class A {

    public static void main(String[] args) {
        int i = 0;
        i = i++;
        System.out.println(i);

        int k = 0;
        k = ++k;
        System.out.println(k);
    }

}

2.执行结果:
执行结果

二、问题二:为什么 ++ 的位置不同会输出不同的结果

Java 代码在执行前会被编译成一个 .class 字节码文件,随后 JVM 会把这份编译好的字节码文件翻译成平台的机器指令

1.生成 .class 文件

javac A.java

2.查看编译之后的 .class 字节码文件

javap -c A

如图所示
javap 命令查看 .class字节码文件

图中的指令涉及到了两个数据结构,一个是操作数栈(operand stack),另一个是局部变量表(local variable),前者是栈,后者是数组
和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。但是和前者不同的是,它不是通过索引来访问,而是通过标准的栈操作—压栈和出栈—来访问的。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用

.class 字节码文件内容如下:

public class A {
  public A();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0 // 0 入栈
       1: istore_1 // 0 出栈给 index = 1 位置的变量 i 进行赋值,赋值为 0
       2: iload_1  // 把 index = 1 位置的变量的值 0 压入栈中,栈顶为 0
       3: iinc          1, 1 // 对 index = 1 位置的变量 i 的值加一,此时 index = 1 位置的变量 i 的值由 0 变成 1
       6: istore_1 // 弹出栈顶的值 0,赋值给 index = 1 位置的变量 i,i 从 1 又变成了 0
       7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      10: iload_1 // 把 index = 1 位置的变量 i 的值 0 压入栈中,栈顶为 0
      11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      14: iconst_0 // 0 入栈
      15: istore_2 // 0 出栈给 index = 2 位置的变量 k 进行赋值,赋值为 0
      16: iinc          2, 1 // 对 index = 2 位置的变量 k 的值加一,此时 index = 2 位置的变量 k 的值由 0 变成 1
      19: iload_2  // 把 index = 2 位置的变量 k 的值 1 压入栈中,栈顶为 1
      20: istore_2 // 弹出栈顶的值 1,赋值给 index = 2 位置的变量 k,即 k 的值由 1 变成 1
      21: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      24: iload_2 // 把 index = 2 位置的变量的值 1 压入栈中,栈顶为 1
      25: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      28: return
}

结果:指令执行到 6: istore_1 位置后,i++ 的结果是 0,指令执行到 20: istore_2 时,++k 的结果是 1

i = i++
等价于
temp = i;
i = i + 1;
i = temp;

// The assignment to variable k has no effect
k = ++k
等价于
k = k = k + 1
所以编译器会警告对变量 k 的赋值没有作用
k = ++k 的编译器警告

猜你喜欢

转载自blog.csdn.net/qq_21586317/article/details/81710826