В Java, должны ли переменные объявляться в верхней части функции или по мере необходимости?

Я очищаю Java-код для тех, кто начинает свои функции, объявляя все переменные вверху и инициализируя их нулями/0/независимо, в отличие от объявления их по мере необходимости.

Каковы конкретные рекомендации для этого? Существуют ли причины оптимизации для одного или другого, или это один из способов просто хорошей практики? Существуют ли случаи, когда приемлемо отклоняться от того, что надлежащий способ сделать это?

Ответ 1

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

Ответ 2

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

Объявление переменных в верхней части функций является задержкой с C (где это было необходимо) и не имеет абсолютно никаких преимуществ (переменная область существует только в исходном коде, в байтовом коде все локальные переменные существуют в последовательности в стеке так или иначе). Просто не делай этого, никогда.

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

Ответ 3

Из Соглашения Java Code, Глава 6 в объявлениях:

6.3 Размещение

Положить объявления только в начале блоков. (Блок - это любой код окруженный фигурными фигурными скобками "{" и "}".) Не ждите, чтобы объявить переменные до их первого использования; это может смутить неосторожный программист и код корзины переносимость в рамках области.

void myMethod() {
    int int1 = 0;         // beginning of method block

    if (condition) {
        int int2 = 0;     // beginning of "if" block
        ...
    }
}

Единственное исключение из правила: индексы для циклов, которые в Java может быть объявлено в инструкции for:

for (int i = 0; i < maxLoops; i++) { ... }

Избегайте локальных объявлений, которые скрывают декларации на более высоких уровнях. Для Например, не объявляйте то же самое имя переменной во внутреннем блоке:

int count;
...
myMethod() {
    if (condition) {
        int count = 0;     // AVOID!
        ...
    }
    ...
}

Ответ 4

Если у вас есть кабионные переменные, используемые в разных изолированных местах внутри тела функции, ваша функция слишком велика.

Если ваша функция удобна для понимания, нет никакой разницы между "все впереди" и "по мере необходимости".

Единственная переменная без переднего плана будет находиться в теле оператора for.

for( Iterator i= someObject.iterator(); i.hasNext(); ) 

Ответ 5

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

Когда я посмотрел на байт-код, сгенерированный местоположением объявления несколько лет назад, я обнаружил, что они более или менее идентичны. Были разные различия в зависимости от того, когда они были назначены. Даже что-то вроде:

for(Object o : list) {
   Object temp = ...;  //was not "redeclared" every loop iteration
}

против

Object temp;
for(Object o : list) {
   temp = ...; //nearly identical bytecoode, if not exactly identical.
}

Вышел более или менее идентичный

Ответ 6

Я делаю то же самое в данный момент. Все переменные в коде, который я перерабатываю, объявляются в верхней части функции. Я видел, как я просматривал это, когда объявлялось несколько переменных, но НИКОГДА не использовалось или они не объявлены, и с ними выполняются операции (например, разбор a String, а затем установка объекта Calendar с датой/значения времени из строки), но тогда полученный объект Calendar НИКОГДА не используется.

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

Ответ 7

Определение переменной в более широкой области, чем это необходимо, затрудняет понимание. Ограниченный объем сигналов указывает на то, что эта переменная имеет значение только для этого небольшого блока кода, и вы не можете думать при чтении дальше. Это довольно важный вопрос из-за крошечной краткосрочной рабочей памяти, которую имеет мозг (он сказал, что в среднем вы можете отслеживать только 7 вещей). Еще одна вещь, которую нужно отслеживать, значительна.

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

Ответ 8

Я думаю, что на самом деле объективно доказывается, что стиль declare-at-top более подвержен ошибкам.

Если вы мутируете тестовый код в любом стиле, перемещая строки случайно (чтобы имитировать слияние, плохое или кто-то бездумно разрезает + вставлять), тогда стиль declare-at-top имеет больше шансов скомпилировать функционально неправильно.

Я не думаю, что у declare-at-the-top есть соответствующее преимущество, которое не сводится к личным предпочтениям.

Итак, предполагая, что вы хотите написать надежный код, научитесь делать заявления "точно в срок".

Ответ 9

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

Ответ 10

Из Руководство по стилю Google Java:

4.8.2.2 Объявлено при необходимости

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

Хорошо, я бы следил за тем, что делает Google, на поверхностном уровне может показаться, что объявление всех переменных в верхней части метода/функции будет "более аккуратным", совершенно очевидно, что было бы полезно объявить переменные как надо. Это субъективно, хотя, что кажется вам интуитивным.

Ответ 11

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