java 使用 += 运算符的最佳实践
java best practices using += operator
我在看书"Beginning Java 8 Fundamentals"。我看到了这一行:
//some code...
sum = sum + i; // Better to use sum += i
//more code...
那么我的疑惑是:真的吗?为什么最好使用 +=
运算符?我以为 +=
运算符只是一个更简化的表达式?如果我使用一种或另一种,对代码性能有何影响?
我认为,这本书提供了使用 +=
作为最佳实践。事实上,sum += i
和 sum = 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 命令
- 将 Program1.java 保存到 java 文件
- 编译代码。 运行
javac Program1.java
- Program1 和 Program2 都应该编译成功。
- 运行
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
我在看书"Beginning Java 8 Fundamentals"。我看到了这一行:
//some code...
sum = sum + i; // Better to use sum += i
//more code...
那么我的疑惑是:真的吗?为什么最好使用 +=
运算符?我以为 +=
运算符只是一个更简化的表达式?如果我使用一种或另一种,对代码性能有何影响?
我认为,这本书提供了使用 +=
作为最佳实践。事实上,sum += i
和 sum = sum + i
我实现了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 命令
- 将 Program1.java 保存到 java 文件
- 编译代码。 运行
javac Program1.java
- Program1 和 Program2 都应该编译成功。
- 运行
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 toE1 = (T) ((E1) op (E2))
, whereT
is the type ofE1
, except thatE1
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