2014-12-06 2 views
-1

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

public void foo() { 
    final int x = 3; 
    final Object z = new Object(); 
    ....... 
} 

Я знаю, что х не может быть изменен, так как оно является окончательным, но есть ли другая причина/объяснений для этого? сравнить без использования окончательного? Или разработчик просто добавил финал к этой переменной, потому что ему просто нравится. Благодарю.

+1

Что вы подразумеваете под «есть ли какая-либо другая причина для этого»? Не могли бы вы уточнить свой вопрос? – abl

ответ

1

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

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

public void foo() { 
    final int x = 3; 
    final Object z = new Object(); 
    new Thread() { 
     public void run() { 
      for(int i = 0; i < x; i++) { 
       System.out.println(z); 
      } 
     } 
    }.start(); 
} 

Для этого необходимо, чтобы x и z были объявлены окончательными. Зачем? Ну, локальные переменные создаются в стеке, и, как только функция возвращается, они полностью исчезают. Но код внутри метода Thread.run(), определенный здесь, все еще может выполняться после того, как функция, которая его создала, вернется. Поскольку переменные являются окончательными, их значения известны JVM в момент создания замыкания, поэтому он может просто скопировать значения в закрытие. Если они не были окончательными, это было бы невозможно, потому что копии будут устаревать, как только будет изменено исходное значение.

+0

Спасибо, я просвещен этим объяснением. – bhadz

1

1) Окончательный класс не может быть продлен

2) Окончательный метод не может быть переопределен

3) конечные поля, параметры и локальные переменные не могут изменить свое значение, как только установить

4) Декларирование примитивных полей окончательной автоматически обеспечивает безопасность потоков для этого поля

5) Очевидно, передает ваше намерение

6) Позволяет компилятору и виртуальной машине выполнять небольшие оптимизации.

7) Ясно, что элементы флагов, которые проще в поведении - в конце, говорят: «Если вы ищете сложность, вы не найдете его здесь».

1

Нет других причин, кроме того, что они не позволяли другим изменять значение (объекты, примитивы), но это не мешает им изменять значения в классе (например, final Dog dog = new Dog() не позволит другим изменить ссылку на объект собаки, но не помешает нам изменить переменную внутри него, например, размерное значение собаки)

+0

Имеет ли оригинальный постер этот ответ? – JClassic

+0

Да, я прочитал это, и я хочу больше от этого отказаться. Ваш ответ приветствуется. – bhadz

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