下面的所有三种方法在功能上都是相同的 - 但是它们都有我认为的风格差异。当这些被编译时,编译器是否会区别对待它们? (我缺乏检查和理解反编译字节码的知识)
// Method 1
private boolean isAcceptableRange(final int a, final int b) {
if ((Math.abs(a - b)) <= range) {
return true;
} else {
return false;
}
}
// Method 2
private boolean isAcceptableRange(final int a, final int b) {
if ((Math.abs(a - b)) <= range) {
return true;
}
return false;
}
// Method 3
private boolean isAcceptableRange(final int a, final int b) {
if ((Math.abs(a - b)) <= range)
return true;
return false;
}
我最初的想法是,由于额外的 else
子句,#1 将是唯一的,其中 #2 和 #3 最终将是相同的。这意味着在优化磁盘/ROM 空间效率和可能的指令效率(考虑嵌入式)时,请使用选项 #2 或 #3。
或者编译器是否知道最终结果并“优化”它?
最佳答案
Or does the compiler know the end result and "optimize" it away?
是的,确实如此。让我们看看生成的字节码:
javap -c -private MyClass.class
javap
:是一个工具(除其他外)可以让您查看 java 类的字节码,它随 JDK 一起提供。-c
:将代码反汇编为字节码-private
:显示类中的私有(private)成员和方法。MyClass.class
:编译后的类
private boolean isAcceptableRange1(int, int);
Code:
0: iload_1
1: iload_2
2: isub
3: invokestatic #1 // Method java/lang/Math.abs:(I)I
6: aload_0
7: getfield #2 // Field range:I
10: if_icmpgt 15
13: iconst_1
14: ireturn
15: iconst_0
16: ireturn
private boolean isAcceptableRange2(int, int);
Code:
0: iload_1
1: iload_2
2: isub
3: invokestatic #1 // Method java/lang/Math.abs:(I)I
6: aload_0
7: getfield #2 // Field range:I
10: if_icmpgt 15
13: iconst_1
14: ireturn
15: iconst_0
16: ireturn
private boolean isAcceptableRange3(int, int);
Code:
0: iload_1
1: iload_2
2: isub
3: invokestatic #1 // Method java/lang/Math.abs:(I)I
6: aload_0
7: getfield #2 // Field range:I
10: if_icmpgt 15
13: iconst_1
14: ireturn
15: iconst_0
16: ireturn
我调用了方法isAcceptableRange1
、isAcceptableRange2
、isAcceptableRange3
。正如您所看到的,所有方法都具有完全相同的字节码。
关于java - 编译器如何处理选择语句变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25146628/