2013-03-25 4 views
0

Я обнаружил, что некоторые Java-IDE имеют это правило о том, чтобы сделать вещи окончательными, даже не спрашивая пользователя. Например, просто открыв файл без каких-либо «окончательных» ключевых слов, среда IDE будет вставлять кучу из них по всему месту, в частности по переменным.Действительно ли ключевое слово Java действительно необходимо в большинстве случаев?

Мой аргумент всегда был: «Если IDE может сделать это алгоритмически, так может JVM»

ли это удержание воды аргумент? Когда разработчики Java должны использовать ключевое слово «final»? Должна ли быть объявлена ​​каждая переменная, которая может быть окончательной?

Спасибо!

+3

переменной должно быть окончательным, если вы хотите сказать другим разработчикам: «Эй, вы не должны» измените это! " –

+0

Я настоятельно рекомендую вам [это] (http://renaud.waldura.com/doc/java/final-keyword.shtml) статью. В некоторых случаях «final» может улучшить производительность вашей программы. – Eich

ответ

12

Мой аргумент всегда был: «Если IDE может сделать это алгоритмический, так может JVM»

ли это удержание воды аргумента?

Nope. Потому что, когда IDE делает это (и я не видел, чтобы он делал это по умолчанию без запроса, даже если вы можете явно настроить его таким образом), разработчик может проверить, что это действительно решение, которое они хотели. Этот предохраняет другой код от действий, связанных с пожеланиями разработчика.

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

Когда разработчики Java должны использовать ключевое слово «final»?

Для полей, когда поле предназначено для инициализации в конструкторе и не изменяется после этого.

Для классов, если вы не создали для своего класса подклассы (ИМО).

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

Для локальных переменных, где вы хотите получить доступ к переменной в анонимном внутреннем классе. (Вы также можете использовать их для других локальных переменных, конечно, я не склонен к этому, но я знаю некоторых людей, которые это делают. Это отличие не видно на коде вне метода, конечно.)

+1

... и для локальных переменных, когда они используются в анонимных классах? – Axel

+0

@Axel: Да, правда. Будем добавлять. –

+0

Спасибо за ответ ... Мне кажется, что вы говорите, что «final» следует использовать, чтобы выразить намерение использовать/модифицировать переменную/метод/класс. Поэтому не было бы правило одеяла автоматически добавлять конечные ключевые слова в поражение цели? Например, IDE может решить, что, поскольку вы фактически не изменяете x, x должен быть объявлен окончательным, но, возможно, это не обязательно ваше намерение о том, как x следует использовать? –

1

Вы слишком расплывчатым, окончательное означает, что многие вещи: http://en.wikipedia.org/wiki/Final_(Java)

Кроме того, посмотреть соответствующую дискуссию: https://softwareengineering.stackexchange.com/questions/115690/why-declare-final-variables-inside-methods, которая связывает со следующим artcle:

http://www.javapractices.com/topic/TopicAction.do?Id=23

Используйте окончательное ключевое слово свободно общаться ваши намерения.Окончательное ключевое слово имеет более чем одно значение:

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

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

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

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

Использования окончательный:

  • четко передает Ваше намерение
  • позволяет компилятор и виртуальную машины для выполнения небольших оптимизаций
  • явно флаги предметов, которые проще в поведении - окончательный говорят, «Если вы ищут сложности, вы не найдете его здесь ».
+0

На самом деле я бы сказал, что два основных контекста: * classes * и поля. Но, разумеется, другие два тоже действительны. –

+0

@JonSkeet - да, прекрасные перегруженные ключевые слова! это простой язык, потому что он имеет только 50 ключевых слов. но многие из них имеют несколько значений. Я смотрю на тебя слишком статично. –

0

Локальная переменная может быть использована в качестве внутреннего класса только если он является final.

Модификатор final может использоваться для защиты от скольжения в методах сеттера.

public void setLimit(int limit) { 
    /*this.*/limit = limit; 
} 

, очевидно, не так; необходимо было поставить this.. Использование final как в

public void setLimit(final int limit) { 
    limit = limit; 
} 

получается, что в ошибке компиляции.

0

Должны ли быть объявлены все переменные, которые могут быть окончательными?

Да.

Многие люди не понимают, насколько компилятор может сделать, чтобы помочь вам избежать общих проблем:

// Final parameters cannot be reassigned. This sometimes happens accidentally 
// and sometimes because people see them as convenient local variables. 
publc void myFunction(final int myIntParam) { 

    // Let's declare a local variable 
    final String myLocalString; 

    // ... there's some code here ... 

    // Here, the compiler knows whether this variable has been assigned 
    // The programmer knows that it has been assigned only once 
    return myLocalString.toUpperCase(Locale.ENGLISH); 
} 
+0

Хотя я полностью согласен с * переменными * экземпляра, я не могу вспомнить последний раз, когда я столкнулся с проблемой, когда я случайно переназначил локальную переменную. Легче видеть все назначения локальной переменной, потому что код метода обычно намного меньше кода для всего класса. (И если это не так, это предполагает, что вы должны реорганизовать метод.) Я нахожу, что модификатор 'final' добавляет слишком много беспорядка, чтобы это стоило здесь. Я был бы достаточно доволен, если бы локальные переменные и параметры были окончательными по умолчанию * по умолчанию. –

+0

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

Смежные вопросы