Есть ли причины сделать все поля и переменные окончательными? - PullRequest
3 голосов
/ 27 марта 2010

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

Так же, как здесь:

private final XMLStreamWriter _xmlStreamWriter;
private final Marshaller _marshaller;
private final OutputStream _documentStream;

private final OutputStream _stylesStream;
private final XMLStreamWriter _stylesStreamWriter;
private final StyleMerger _styleMerger;

public DocumentWriter(PhysicalPackage physicalPackage) throws IOException {
    final Package pkg = new Package(physicalPackage);

    final Part wordDocumentPart = pkg.createPart(
            "/word/document.xml",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");

    // styles.xml
    final Pair<Part, String> wordStylesPart = wordDocumentPart.createRelatedPart(...);
    ...
}

Есть ли для этого причины?

p.s. Как я знаю, проект не должен быть многопоточным (по крайней мере, я ничего об этом не слышал).

Ответы [ 5 ]

4 голосов
/ 27 марта 2010

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

Ключевое слово final может помочь преобразовать логические ошибки в ошибки компилятора без особых усилий.

Например:

public int test(int num){
   num = 10;
   x = num*2
   return  x;
}

В приведенном выше примере мы могли бы случайно присвоить новое значение переменной num, чтобы возвращаемое значение было неправильным. С помощью ключевого слова final мы предотвращаем подобные ошибки.

public int test(final int num){
       num = 10; //compiler error
       x = num*2
       return  x;
    }
4 голосов
/ 27 марта 2010

Когда вы пишете final, вы сообщаете и компилятору, и читателю, что эта переменная установлена ​​один раз, а затем не изменяется.

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

Человек-читатель может использовать его для более быстрого понимания цели кода.

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

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

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

2 голосов
/ 27 марта 2010

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

0 голосов
/ 27 марта 2010

И практически объект находится в 2 или даже больше загрузчиков классов, таких как среда сервера приложений, и, следовательно, будет назначен несколько раз, даже окончательно. Или загрузите объявленный финал из файла свойств, который позже был изменен, случившееся здесь, удаление объявленных финальных и обычных переменных стало более прагматичным.

0 голосов
/ 27 марта 2010

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

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