Конечная переменная и синхронизированный блок в Java - PullRequest
6 голосов
/ 20 января 2010

Что такое конечная переменная в Java? Например: если я напишу final int temp; в функции, что означает последнее ключевое слово?
Кроме того, когда я хотел бы использовать конечную переменную (как переменную класса, так и переменную функции)?
Почему переменные в синхронизированном блоке должны быть объявлены окончательными?

Ответы [ 3 ]

14 голосов
/ 20 января 2010

Конечные переменные и синхронизированные блоки кода имеют что-то общее ... Если вы объявите неконечную переменную a, а затем напишите synchronized (a) { System.out.println('xxx'); }, вы получите предупреждение "Синхронизация в неконечном поле" - по крайней мере, в NetBeans .

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

Посмотрите здесь пример реальных проблем, вызванных синхронизацией в не финальном поле: http://forums.sun.com/thread.jspa?threadID=5379204

14 голосов
/ 20 января 2010

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

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

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

РЕДАКТИРОВАТЬ: Комментарий Wildwezyr имеет смысл с точки зрения не изменения переменной , с которой вы синхронизируете . Это было бы опасно по причинам, которые он дал. Это то, что вы имели в виду под «переменной в синхронизированном блоке»?

4 голосов
/ 20 января 2010

В дополнение к тому, что сказал Джон Скит, значение нельзя изменить, но содержимое можно изменить.

final Integer one = new Integer(1);
...
one = new Integer(2); // compile error

final List list = new ArrayList();
...
list = new ArrayList(); // compile error
list.add(1); // Changes list, but that's fine!

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

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

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