Точка наличия переменной экземпляра в качестве окончательной?

В чем смысл иметь переменную экземпляра как final?

Не лучше ли, чтобы эта переменная была задана как статическая конечная переменная?

вызвать, если он не может быть изменен каким-либо из объектов, тогда он будет таким же, как переменная класса (статическая), правильно?

Ответ 1

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

Есть много причин, по которым вы можете сделать переменную final; одним из лучших является ясность. Если я прочитаю метод и заметлю, что foo является окончательным, мне не нужно беспокоиться о том, где он меняется ниже - потому что это не так; он не может. Я могу сделать больше изменений в коде с конечными переменными с меньшим беспокойством ( "изменил ли значение foo до или после строки, и это имеет значение?" ), Потому что я знаю, что некоторые переменные не подлежат изменению. Он также фокусирует мое внимание на переменных, которые могут быть изменены - и они заслуживают большего внимания.

Ответ 2

Две причины:

1) Из представления дизайна класса он позволяет программисту полагаться на то, что поле не изменится с момента создания - так называемый " неизменяемый объект". Учебник Java говорит:

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

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

2) Вторая причина - оптимизация JVM. Если все поля являются окончательными, то JVM знает, что состояние объекта не может быть изменено и, таким образом, оно может сделать много оптимизаций, например. ommiting проверки безопасности и т.д.

Ответ 3

Я думаю, вы думаете о простом случае, например:

 private final int num = 3;

Это может быть лучше написано как:

 private static final int NUM = 3;

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

 private final List<Node> children = new ArrayList<Children>();

Или, возможно, значение, переданное или выведенное в конструкторах:

 public final class MyThing {
      private final String name;
      public MyThing(String name) {
          this.name = name;
      }
      [...]
 }

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

Ответ 4

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

Ответ 5

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

Ответ 6

class A{
public final int x;

A(int arg){
    x = arg; // This is legal!!
}

}

открытый класс HelloWorld {

 public static void main(String []args){
     A  a = new A(1);
     A  b = new A(2);
     System.out.printf("a.x = %d, b.x = %d", a.x, b.x);
 }

}