Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-在for循环中声明变量_Java_Micro Optimization - Fatal编程技术网

Java-在for循环中声明变量

Java-在for循环中声明变量,java,micro-optimization,Java,Micro Optimization,在循环中声明变量是一种糟糕的做法吗?在我看来,这样做,如下面第一个代码块所示,将使用第二个代码块十倍的内存。。。由于在循环的每次迭代中创建一个新字符串。这是正确的吗 for (int i = 0; i < 10; i++) { String str = "Some string"; } for(int i=0;i

在循环中声明变量是一种糟糕的做法吗?在我看来,这样做,如下面第一个代码块所示,将使用第二个代码块十倍的内存。。。由于在循环的每次迭代中创建一个新字符串。这是正确的吗

for (int i = 0; i < 10; i++) {
  String str = "Some string";
}
for(int i=0;i<10;i++){
String str=“Some String”;
}
vs

String-str;
对于(int i=0;i<10;i++){
str=“一些字符串”;
}
在循环中声明变量是一种糟糕的做法吗

一点也不!它将变量定位到其使用点

在我看来,这样做,如下面第一个代码块所示,将使用第二个代码块十倍的内存

编译器可能会优化一些东西,以保持内存使用效率。仅供参考:如果您使用
final
关键字告诉它您的变量有一个对对象的固定引用,您可以帮助它


注意:如果您有一个更复杂的对象,在构造函数中执行复杂的代码,那么您可能需要担心单次执行与多次执行,并在循环之外声明该对象。

变量引用使用的内存很小。在循环中声明项通常是更好的做法,因为它将更接近使用它的位置,更具可读性。

这取决于具体情况。效率低下的原因是,假设编译器不做任何更改,那么创建字符串对象的开销很大。一旦内存超出范围,它就会被清除。

在这两个示例中,您将实例化一个新的string对象,该对象包含相同次数的字符串“Some string”

在第一个示例中,在循环内部声明
str
,在for循环完成后,对该字符串的所有引用都将丢失,从而允许Java的垃圾收集器从内存中删除字符串的所有实例。但是,在第二个示例中,您在循环外部声明
str
,您创建的最后一个字符串仍然在循环外部有一个对它的引用,Java的垃圾收集器只会从内存中删除实例化的10个字符串中的9个


因此,第一种方法更好,因为您不保留字符串的任何引用,这会干扰垃圾收集器确定它是否仍在使用的能力。

除了@Jason s所说的,我还鼓励您考虑代码的可读性

例如,如果您只向一个引用写入一次,则可以更清楚地使用以下内容:

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次的循环内,它将构造N个单独的对象,而在循环外,它将执行一次。但是如果你有
final Foo foo1=new Foo(someArg)在循环外部,然后
final Foo Foo=foo1
在循环内部,只能实例化一个对象。字符串有点特殊,因为它们是不可变常量,编译器可能会优化它,创建一个字符串对象,并在循环中每次重复使用它。变量引用使用的内存确实很小。但是如果循环从0迭代到1000000000,并且使用代码块#2只使用一个变量引用(与块#1的每次迭代使用一个变量引用相反),您肯定会看到这将是一个问题。是的,即使循环那么多次,这也不会有太大的区别。正如其他人所说,编译器甚至可能会对其进行优化,您可以对其进行测试并确定结果。但是,无论哪种方式,使代码更难阅读的成本都不值得对性能进行一点小小的改进。。如果我们有String str=newstring(“Some String”);消息灵通的我的理解是,它将创建10个实例@拉维:你可能是对的,因为你显式调用了
String
构造函数,我很确定它绕过了重复使用常量字符串实例的字符串内部操作。但即使在这种情况下,如果你将str声明移到循环外,而将赋值留在循环内,您仍然会创建相同的10个实例。@ILMTitan:是的,您是对的。我只是想知道JVM是否会优化,即使有一个新的操作员。它会创建十个实例,是的,但是你必须做九千次以上才能获得显著的性能影响。将变量保留在作用域中允许运行时快速释放该变量(并在迭代过程中重复使用)——将变量移动到周围的作用域将使其在内存中保留更长的时间。不管怎样,您仍然会为每个迭代重新创建对象实例。
String str = null;
while(condition){
    str = "write once";
    //do stuff with str
}