Что делает "final", если вы помещаете его перед переменной? - PullRequest
43 голосов
/ 25 октября 2010

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

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

Что делает final?

Ответы [ 8 ]

70 голосов
/ 25 октября 2010

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

Останавливает присвоение переменной myTextField чему-либо другому.

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

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

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

15 голосов
/ 25 октября 2010

Ключевое слово 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);
10 голосов
/ 25 октября 2010

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

FOLLOWUP

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

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

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

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

4 голосов
/ 25 октября 2010

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

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

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

3 голосов
/ 11 января 2012

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

3 голосов
/ 25 октября 2010

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

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

2 голосов
/ 25 октября 2010

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

0 голосов
/ 28 сентября 2018

Попытка объяснить использование модификатора final с потоком кода:

public static void main(String[] args) {

    class Person {
        String name;
    }

    Person peep1 = new Person(); // points to obj at address HEX001
    peep1.name = "Mike"; 
    System.out.println(peep1.name);

    Person peep2 = new Person(); // points to obj at address HEX002
    peep2.name = "Jenna";
    System.out.println(peep2.name);

    final Person peep3 = peep1; // also points to obj at address HEX001
    System.out.println(peep3.name);

    peep1.name = "pwnd"; // modifies obj at address HEX001
    System.out.println(peep1.name);
    System.out.println(peep3.name);

    peep1 = peep2; // now it points to obj at address HEX002
    System.out.println(peep1.name);

    System.out.println(peep3.name); // still points to obj at address HEX001

    peep2.name = "Henna"; // modifies obj at address HEX002
    System.out.println(peep2.name);

    peep3 = peep2; // compiler error "The final local variable peep3 cannot be assigned. It must be
                    // blank and not using a compound assignment"

    System.out.println(peep3.name); // assuming it now points to obj at address HEX002

}

Выход:

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