dac*_*cwe 16

首先,Java语言规范没有说明时序.不过,假设我们使用一个典型的编译器,如太阳的javac我们看到,所有上面的例子(a++,++a,a += 1,a = a + 1)既可以被编译成这样的:

编译器可以选择最好的编译方式.例如,它们之间没有区别.并且它们之间不应该有任何区别 - 它们都表达相同的东西 - 在数字中添加一个.

该说,可以使用JIT iinciadd版本编译为快速且依赖于平台的版本,最后我假设普通运行时将两个版本编译为相同的汇编代码.


使用我的编译器,*jdk1.6.0_20*"增量"方法甚至使用相同的指令.

public class Test {
    public static void main(String[] args) {

        int a = 0;

        a = a + 1;
        a += 1;
        a++;
        ++a;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是反汇编:

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

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iinc    1, 1   // a = a + 1;
   5:   iinc    1, 1   // a += 1;
   8:   iinc    1, 1   // a++;
   11:  iinc    1, 1   // ++a;
   14:  return

}
Run Code Online (Sandbox Code Playgroud)


ben*_*y23 3

查看生成的字节码:

public static void main(String[] args) {
    int x = 1;
    int y = 1;
    int z = 1;
    int a = 1;
    int b = 1;
    x = x + 1;
    y++;
    ++z;
    a += 1;
    b += 2;
}
Run Code Online (Sandbox Code Playgroud)

生成(使用javap -c classname

0:   iconst_1
1:   istore_1
2:   iconst_1
3:   istore_2
4:   iconst_1
5:   istore_3
6:   iconst_1
7:   istore  4
9:   iconst_1
10:  istore  5
12:  iload_1
13:  iconst_1
14:  iadd
15:  istore_1
16:  iinc    2, 1
19:  iinc    3, 1
22:  iinc    4, 1
25:  iinc    5, 2
28:  return
Run Code Online (Sandbox Code Playgroud)

所以使用(jdk1.6.0_18):

x = x + 1
Run Code Online (Sandbox Code Playgroud)

创造

12:  iload_1
13:  iconst_1
14:  iadd
15:  istore_1
Run Code Online (Sandbox Code Playgroud)

然而

y++;
++z;
a += 1;
Run Code Online (Sandbox Code Playgroud)

全部导致

iinc
Run Code Online (Sandbox Code Playgroud)

然而,在我的笔记本电脑上进行粗略的性能测试导致两者之间的运行时间几乎没有差异(有时 ++x 更快,有时 x=x+1 更快),所以我不担心性能影响。