java 使用 += 运算符的最佳实践

java best practices using += operator

我在看书"Beginning Java 8 Fundamentals"。我看到了这一行:

//some code...
sum = sum + i; // Better to use sum += i
//more code...

那么我的疑惑是:真的吗?为什么最好使用 += 运算符?我以为 += 运算符只是一个更简化的表达式?如果我使用一种或另一种,对代码性能有何影响?

我认为,这本书提供了使用 += 作为最佳实践。事实上,sum += isum = sum + i

的 2 个语句之间没有区别

我实现了2个类,每个包含一个语句,用命令javap

看字节码

这是程序 1:

public class Program1 {
     public static void main(String []args) {
        int i = 1;
        int sum = 2;
        sum += i;
     }
}

这里是字节码:

public class Program1 {
  public Program1();
    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_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: istore_1
       8: return
}

这是程序 2:

public class Program2 {
    public static void main(String []args) {
        int i = 1;
        int sum = 2;
        sum = sum + i;
    }
}

这里是字节码:

public class Program2 {
  public Program2();
    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_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: istore_1
       8: return
}

如上所示,字节码相同,所以语句相同。没有区别。

编辑 1:如何 运行 javap 命令

  1. 将 Program1.java 保存到 java 文件
  2. 编译代码。 运行javac Program1.java
  3. Program1 和 Program2 都应该编译成功。
  4. 运行 javap -c Program1.class 看字节码。

编辑2:变量类型不同时运算符的区别

+= 运算符有一个隐式转换为左操作符,因此如果变量的类型不同 += 运算符将自动转换。

这是代码

long i = 1;
int sum = 2;
sum += i; //means sum = (int)(i + sum)

此外,sum = sum + i没有隐式转换,这条语句不会编译。

如果需要强制转换,我通常使用显式强制转换。这使代码更具可读性和安全性。

没有性能差异。一种方式可能读起来稍微好一点。

可以说 sum += i; 是更好的风格,因为它不是多余的,reader 可能需要稍微少一点的工作来弄清楚 += 是怎么回事,因为没有必要在赋值运算符的两边寻找和。

"Best practices" 对可读性和可维护性的关注至少与对性能的关注一样多,不要假设一切都与性能有关。

在一些涉及隐式转换的模糊情况下使用 += 可能会出现问题。有一个 Java 益智游戏(来自 Bloch 和 Gafter 的书)设法滥用了它,see this question

正如@Trinimon 评论的那样,+=+ 运算符之间存在差异:

E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once. (§15.26.2 Compound Assignment Operators)

所以

int sum = 0;
sum += 1.0; // this is equivalent to sum = (int) (sum + 1.0);
sum = sum + 1.0; // this will not compile
                 // incompatible types: possible lossy conversion from double to int

与常识相反,使用+=运算符更安全。

好问题!

参考

Java's +=, -=, *=, /= compound assignment operators