为什么下面的工作正常?
String str;
while (condition) {
str = calculateStr();
.....
}
但是下面这个被认为是危险的/不正确的:
while (condition) {
String str = calculateStr();
.....
}
有必要在循环之外声明变量吗?
为什么下面的工作正常?
String str;
while (condition) {
str = calculateStr();
.....
}
但是下面这个被认为是危险的/不正确的:
while (condition) {
String str = calculateStr();
.....
}
有必要在循环之外声明变量吗?
当前回答
变量的声明应该尽可能靠近使用它们的地方。
它使RAII(资源获取初始化)更容易。
它使变量的范围保持紧凑。这让优化器工作得更好。
其他回答
我认为物体的大小也很重要。 在我的一个项目中,我们声明并初始化了一个大型二维数组,该数组使应用程序抛出内存不足异常。 我们将声明移出循环,并在每次迭代开始时清除数组。
在while循环之外声明String str允许它在while循环内外被引用。在while循环中声明String str只允许它在while循环中被引用。
在这个问题上对几乎所有人的警告:下面是示例代码,在我的Java 7计算机上,循环内部的速度很容易慢200倍(内存消耗也略有不同)。但这不仅关乎范围,还关乎分配。
public class Test
{
private final static int STUFF_SIZE = 512;
private final static long LOOP = 10000000l;
private static class Foo
{
private long[] bigStuff = new long[STUFF_SIZE];
public Foo(long value)
{
setValue(value);
}
public void setValue(long value)
{
// Putting value in a random place.
bigStuff[(int) (value % STUFF_SIZE)] = value;
}
public long getValue()
{
// Retrieving whatever value.
return bigStuff[STUFF_SIZE / 2];
}
}
public static long test1()
{
long total = 0;
for (long i = 0; i < LOOP; i++)
{
Foo foo = new Foo(i);
total += foo.getValue();
}
return total;
}
public static long test2()
{
long total = 0;
Foo foo = new Foo(0);
for (long i = 0; i < LOOP; i++)
{
foo.setValue(i);
total += foo.getValue();
}
return total;
}
public static void main(String[] args)
{
long start;
start = System.currentTimeMillis();
test1();
System.out.println(System.currentTimeMillis() - start);
start = System.currentTimeMillis();
test2();
System.out.println(System.currentTimeMillis() - start);
}
}
结论:根据局部变量的大小,即使变量不是那么大,差异也可能是巨大的。
只是说,有时候,在循环外或循环内确实很重要。
在循环中声明将限制各自变量的范围。这完全取决于项目对变量范围的要求。
我认为回答你的问题最好的资源是下面的帖子:
在循环前或循环中声明变量的区别?
根据我的理解,这个东西是语言依赖的。IIRC Java优化了这一点,所以没有任何区别,但JavaScript(例如)将在每次循环中完成整个内存分配。特别是在Java中,我认为当完成分析时,第二个程序会运行得更快。