Подтвердить что ты не робот

Что делает "final", если вы поместите его перед переменной?

Очень простой вопрос, но что делает "final", если вы поместите его перед переменной, такой как ниже...

final EditText myTextField = (EditText) findViewById(R.id.myTextField);

Что делает final?

4b9b3361

Ответ 1

Короткий ответ

Останавливает переменную myTextField, которой присваивается что-то еще.

Длинный ответ

  • НЕ останавливает изменение переменной myTextField, например. с его полями установлены новые значения.
  • Делает код более удобочитаемым (IMHO), потому что читателю никогда не нужно задаваться вопросом, будет ли позже изменена переменная myTextField в коде.
  • Охраняется от категории ошибок, при которой переменные случайно переназначаются (та же аргументация по поводу того, что экземпляры неизменяемы, только в меньших масштабах).

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

Ответ 2

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

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

Runnable r = new Runnable() { public static void run() {
         // do something with myTextField
         // this would require myTextField to have been marked final.
}};
doSomethingLater(r);

Ответ 3

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

Followup

Является ли это конкретным JVM?

Спецификация модели памяти Java является частью спецификации языка Java, и (AFAIK) не изменилась с Java 1.5. В этом смысле это не специфический JVM.

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

Помимо всего прочего, модель памяти Java предназначена для того, чтобы позволить многоядерным машинам запускать многие потоки Java без необходимости постоянно скрывать кеширование памяти... что может привести к гибели производительности. В основном, он определяет некоторые правила, которые гарантируют, что один поток Java видит обновления памяти из другого потока. Если приложение не соответствует правилам, возможно, что поток увидит устаревшее (устаревшее) значение для некоторого поля, написанного каким-то другим потоком, что приведет к случайному поведению undefined.

Ответ 4

Ключевое слово final гарантирует, что myTextField содержит ссылку на все, что findViewByID() возвращает и запрещает любое другое назначение переменной myTextField i.e после выполнения

final EditText myTextField = (EditText) findViewById(R.id.myTextField);

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

Ответ 5

Вы не можете изменить ссылку myTextField после ее назначения. Более подробная информация ниже из Wikipedia

Конечная переменная может быть назначена один раз. Это задание не дает переменный неизменный статус. Если variable - поле класса, оно должен быть назначен в конструкторе его классом. (Примечание: если переменная является эта ссылка означает, что переменная не может быть привязана к ссылка другой объект. Но объект, который он ссылается, по-прежнему изменчивый, если он был первоначально mutable.) В отличие от значения константа, значение окончательного переменная не обязательно известна в время компиляции.

Ответ 6

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

Ответ 7

Ключевое слово final объявляет myTextField как константную переменную.