在循环内部声明变量是不良实践吗?我认为像下面第一个代码块中所示这样做会使用十倍的内存,因为每次循环迭代都会创建一个新字符串。这是正确的吗?
for (int i = 0; i < 10; i++) {
String str = "Some string";
}
对比。
String str;
for (int i = 0; i < 10; i++) {
str = "Some String";
}
在循环内部声明变量是不良实践吗?我认为像下面第一个代码块中所示这样做会使用十倍的内存,因为每次循环迭代都会创建一个新字符串。这是正确的吗?
for (int i = 0; i < 10; i++) {
String str = "Some string";
}
对比。
String str;
for (int i = 0; i < 10; i++) {
str = "Some String";
}
String
构造函数,我相当确定这会绕过字符串池化操作,从而无法重用常量字符串实例。 - Jason Sstr
,所有对该字符串的引用都将在for循环完成后丢失,从而允许Java的垃圾收集器从内存中删除所有字符串实例。但是,在第二个例子中,您在循环外部声明str
,您创建的最后一个字符串仍将在循环外部具有对它的引用,Java的垃圾收集器只会从内存中删除10个字符串中的9个实例。String str = "write once";
while(condition){
//do stuff with str
}
对比:
String str = null;
while(condition){
str = "write once";
//do stuff with str
}
这要看情况。如果您的编译器没有做任何更改,那么低效率是由于创建String对象时产生的开销。一旦超出作用域,内存将被清除。
final Foo foo = new Foo(someArg);
,它将构造N个不同的对象;而在循环外部执行则只会构造一次。但是,如果您在循环外部执行final Foo foo1 = new Foo(someArg);
,然后在循环内部执行final Foo foo = foo1
,那么只会实例化一个对象。字符串有点特殊,因为它们是不可变常量,编译器可能会将其优化为创建一个String对象,并在循环中重复使用它。 - Jason S