Java - объявление переменных для циклов

Объявляет переменную внутри плохой практики цикла? Мне кажется, что это, как видно из первого блока кода ниже, будет использовать в десять раз больше, чем память... из-за создания новой строки на каждой итерации цикла. Правильно ли это?

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

против.

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

Ответы

Ответ 1

Объявляет переменную внутри плохой практики цикла?

Совсем нет! Он локализует переменную до точки ее использования.

Мне кажется, что, делая это, как показано в первом блоке кода ниже, будет использовать в десять раз больше памяти в качестве второго

Компилятор может оптимизировать работу, чтобы обеспечить эффективное использование памяти. FYI: вы можете помочь, если вы используете ключевое слово final, чтобы сообщить ему, что ваша переменная имеет фиксированную ссылку на объект.

Примечание. Если у вас есть более сложный объект, где вы выполняете сложный код в конструкторе, вам может потребоваться беспокоиться о одиночном или множественном выполнении и объявить объект за пределами цикла.

Ответ 2

В обоих примерах вы собираетесь создать экземпляр нового строкового объекта, который содержит строку "Some String" столько же раз.

В первом примере, где вы объявляете str внутри цикла, все ссылки на эту строку будут потеряны после завершения цикла for-loop, что позволит сборщику мусора Java удалить все экземпляры строк из памяти. Однако во втором примере, где вы объявляете str вне цикла, последняя строка, которую вы создали, по-прежнему будет иметь ссылку на нее вне цикла, а сборщик мусора Java будет удалять только 9 из 10 строк из памяти, которые были созданы.

Таким образом, первый метод лучше, поскольку вы не держитесь за какие-либо ссылки на строку, мешая способности сборщика мусора определить, используется ли он еще.

Ответ 3

Помимо того, что сказал @Jason S, я также рекомендую вам подумать о читабельности кода.

Например, если вы только пишете ссылку на ссылку один раз, это сделает вашу цель более понятной, чтобы использовать что-то вроде:

String str = "write once";
while(condition){
    //do stuff with str
}

Versus:

String str = null;
while(condition){
    str = "write once";
    //do stuff with str
}

Аналогично, если значение строки действительно основано на том, что является специфическим для итерации цикла, объявите переменную внутри цикла.

Ответ 4

Память, используемая ссылкой переменной, мала. Обычно лучше всего объявлять элемент внутри цикла, потому что он будет ближе к тому, где он используется, и более читаемым.

Ответ 5

Это зависит. Неэффективность - это накладные расходы, создающие объект String, предполагая, что ваш компилятор ничего не меняет. Память будет очищена, если она выходит из области видимости.