смысл иметь переменную экземпляра в качестве финала? - PullRequest
13 голосов
/ 13 января 2010

Какой смысл иметь переменную экземпляра в качестве финала?

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

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

Ответы [ 6 ]

25 голосов
/ 13 января 2010

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

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

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

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

 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 голосов
/ 13 января 2010

Две причины:

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

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

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

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

2 голосов
/ 13 января 2010

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

0 голосов
/ 23 декабря 2018
class A{
    public final int x;

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

public class 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);
     }
}
0 голосов
/ 13 января 2010

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

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