Объявление переменных внутри или вне цикла - PullRequest
212 голосов
/ 10 января 2012

Почему следующее работает нормально?

String str;
while (condition) {
    str = calculateStr();
    .....
}

Но этот называется опасным / неправильным:

while (condition) {
    String str = calculateStr();
    .....
}

Необходимо ли объявлять переменные вне цикла?

Ответы [ 20 ]

2 голосов
/ 23 января 2012

Как много людей указали,

String str;
while(condition){
    str = calculateStr();
    .....
}

НЕ лучше, чем это:

while(condition){
    String str = calculateStr();
    .....
}

Так что не объявляйте переменные вне их областей, если вы не используете их повторно ...

2 голосов
/ 23 января 2012

Согласно руководству по разработке Google Android, область действия переменной должна быть ограничена.Пожалуйста, проверьте эту ссылку:

Предел переменной области

2 голосов
/ 23 января 2012

Переменные должны быть объявлены как можно ближе к месту их использования.

Это облегчает RAII (Инициализация ресурсов - это инициализация) .

Сохраняет область видимости переменной. Это позволяет оптимизатору работать лучше.

1 голос
/ 10 января 2012

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

1 голос
/ 20 января 2012

Действительно, вопрос, изложенный выше, является проблемой программирования. Как бы вы хотели запрограммировать свой код? Где вам нужен STR для доступа? Нет смысла объявлять переменную, которая используется локально как глобальная переменная. Основы программирования я считаю.

0 голосов
/ 09 августа 2017

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

0 голосов
/ 07 мая 2015

Переменная str будет доступна и зарезервирует некоторое пространство в памяти даже после выполнения кода ниже.

 String str;
    while(condition){
        str = calculateStr();
        .....
    }

Переменная str будет недоступна, а также будет освобождена память, выделенная для переменной str в приведенном ниже коде.

while(condition){
    String str = calculateStr();
    .....
}

Если мы последуем второму примеру, это наверняка уменьшит нашу системную память и увеличит производительность.

0 голосов
/ 21 ноября 2014

Предупреждение для почти всех в этом вопросе: Вот пример кода, где внутри цикла он может быть в 200 раз медленнее на моем компьютере с Java 7 (и потребление памяти также немного отличается) Но речь идет о распределении, а не только о масштабах.

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);
    }
}

Вывод: в зависимости от размера локальной переменной, разница может быть огромной, даже с небольшими переменными.

Просто сказать, что иногда, вне или внутри цикла, имеет значение.

0 голосов
/ 23 января 2012

Эти два примера приводят к одному и тому же.Однако первый предоставляет вам возможность использовать переменную str вне цикла while;второй нет.

0 голосов
/ 22 ноября 2012

У вас есть риск NullPointerException, если ваш метод calculateStr() вернет null , а затем вы попытаетесь вызвать метод на стр.

В целом, избегайте использования переменных с ноль значение.Это сильнее для атрибутов класса, кстати.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...