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

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

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

и

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

5 ответов


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

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

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

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

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


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

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

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


помимо того, что сказал @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
}

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


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


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