带循环变量的java作用域
今天,我们在工作中讨论了以下两个函数中哪一个性能更好,内存消耗更少,并且不强调gc
public class Main {
public void do1() {
int result = 0;
int val;
do {
val = calc(result);
result = val * 2;
} while (result < 1000);
}
public void do2() {
int result = 0;
do {
final int val = calc(result);
result = val * 2;
} while (result < 1000);
}
private int calc(final int i) {
return i + 2;
}
}
在我看来,两者都是等价的,无论val是在循环内部还是外部定义的。我唯一想到的是变量的范围应该尽可能地缩小。但是,在讨论gc如何处理这些情况时,我们没有找到解决方案
我们看了字节码,没有区别
Compiled from "Main.java"
public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void do1();
Code:
0: iconst_0
1: istore_1
2: aload_0
3: iload_1
4: invokespecial #2 // Method calc:(I)I
7: istore_2
8: iload_2
9: iconst_2
10: imul
11: istore_1
12: iload_1
13: sipush 1000
16: if_icmplt 2
19: return
public void do2();
Code:
0: iconst_0
1: istore_1
2: aload_0
3: iload_1
4: invokespecial #2 // Method calc:(I)I
7: istore_2
8: iload_2
9: iconst_2
10: imul
11: istore_1
12: iload_1
13: sipush 1000
16: if_icmplt 2
19: return
}
有人知道这里是否真的没有区别,或者可以解决讨论吗
# 1 楼答案
没有区别。由于没有分配
new
对象,因此这两个对象都与垃圾收集器没有任何交互int
变量在堆栈上分配这反映在每个相同的字节码中
# 2 楼答案
正如您在检查字节码时所看到的,Java中没有任何区别。您可能会在其他语言中看到一些差异,例如,如果用C编写相同的代码
所以在你的例子中,争论是关于化妆品和可维护性的
我认为使用最具体的作用域级别(如
do2
)更好,如下所示:不同的观点,但在您的示例中,我甚至认为可以在下一个表达式中内联
val
变量。不这样做只会增加噪音。但我假设这样做是为了示例或打印值