本文主要介绍 Java 中的++i
和 i++
的区别。
概念
在 Java 中,自增是一种非常常见的操作。其中包含两种写法:一种是 ++i
称为前递增运算符(前缀自增),另一种 ++i
称为后递增运算符(后缀自增)。顾名思义,前递增运算符在使用前递增变量,而后递增运算符在使用后递增变量。也属于一元运算符范畴。
作用
增量运算符通常在循环中使用,以自动执行循环迭代。
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
System.out.println("循环使用i++: ");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
System.out.println("================");
System.out.println("循环使用++i: ");
for (int i = 0; i < arr.length; ++i) {
System.out.println(arr[i] + " ");
}
}
运行结果:
可见在for循环中,它们的使用没有明显区别。
区别
(1)含义不同
两者处理方式不同:++i 是从内存中加载 i,然后加1,再使用(赋值),最后存到内存中。而 i++ 是从内存中加载 i,使用(赋值),再加1,最后存到内存中。
在下面示例中,我们可以清楚地看到i++与++i之间的区别。
public static void main(String[] args) {
int a = 0;
System.out.println(a++); // 0
int b = 0;
System.out.println(++b); // 1
}
分析:对int a来说,我们对其应用i++形式自增,因为递增的操作在使用之后(这里指打印),所以a输出的是原值0;int b是在使用前执行自增,因此该变量输出的是1。
(2)性能差异
如前所述,这两种自增在某些情况下的性能是有差别的。原因在于++i 操作是变量本身加1返回,而 i++ 则是创建一个新变量,得到原有变量之后加1返回。因此,后缀自增的过程会创建一个新变量,在编译器没有优化的情况下,后缀自增的速度比前缀自增慢一点点。
代码测试:
public class OperatorTest04 {
public static void main(String[] args) {
OperatorTest04 opt = new OperatorTest04();
long maxIteration = 1000000000L;
System.out.println("<========== i++ 循环 ==========>");
long start = System.currentTimeMillis();
for (long i = 0; i < maxIteration; i++) {
opt.post();
}
System.out.println("后缀自增:" + ((System.currentTimeMillis()) - start) + "ms");
System.out.println("<========== ++i 循环 ==========>");
long start2 = System.currentTimeMillis();
for (long i = 0; i < maxIteration; ++i) {
opt.pre();
}
System.out.println("前缀自增:" + ((System.currentTimeMillis()) - start2) + "ms");
System.out.println("<========== 直接+1 循环 ==========>");
long start3 = System.currentTimeMillis();
for (long i = 0; i < maxIteration; ++i) {
opt.plusEquals();
}
System.out.println("加1赋值:" + ((System.currentTimeMillis()) - start3) + "ms");
}
private int post() {
int a = 0;
a++;
return a;
}
private int pre() {
int a = 0;
++a;
return a;
}
private int plusEquals() {
int a = 0;
a += 1;
return a;
}
}
运行结果:
根据循环1000000000次后的时间来看,尽管每次运行的速度有细微差别,但是总体上++i自增比i++自增要快一点点,而加1赋值则相对不稳定。
总结
一般来说,经过优化的编译器,前缀自增和后缀自增在循环中应该会被编译成相同的字节码,不会有速度上的差异。为了保险起见,推荐写++i这种方式。