Инициализировать статическое конечное поле в конструкторе - PullRequest
79 голосов
/ 23 февраля 2011
public class A 
{    
    private static final int x;

    public A() 
    {
        x = 5;
    }
}
  • final означает, что переменная может быть назначена только один раз (в конструкторе).
  • static означает, что это экземпляр класса.

Я не понимаю, почему это запрещено. Где эти ключевые слова мешают друг другу?

Ответы [ 7 ]

171 голосов
/ 23 февраля 2011

Конструктор будет вызываться каждый раз, когда создается экземпляр класса.Таким образом, приведенный выше код означает, что значение x будет повторно инициализироваться при каждом создании экземпляра.Но поскольку переменная объявлена ​​как final (и static), вы можете сделать это только

class A {    
    private static final int x;

    static {
        x = 5;
    }
}

Но если вы удалите static, вам будет разрешено сделать следующее:

class A {    
    private final int x;

    public A() {
        x = 5;
    }
}

ORэто:

class A {    
    private final int x;

    {
        x = 5;
    }
}
16 голосов
/ 23 февраля 2011

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

Если вам нужна настраиваемая логика для инициализации статического конечного поля, поместите его в статический блок

6 голосов
/ 23 февраля 2011

Подумайте о том, что происходит во второй раз, когда вы создаете объект.Он пытается установить его СНОВА, что явно запрещено статическим финалом.Он может быть установлен только один раз для всего класса, но не для экземпляра.

Вы должны установить значение при его объявлении

private static final x=5;

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

5 голосов
/ 23 февраля 2011

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

Если вы установите его в конструкторе, вы позволите установить переменную более одного раза.

Следовательно, вы должны инициализировать его напрямую или предложитьстатический метод для его инициализации.

3 голосов
/ 23 февраля 2011

Final не означает, что его нужно инициализировать в конструкторе.Как правило, это то, что делается:

 private static final int x = 5;

static вместо этого означает, что переменная будет совместно использоваться несколькими экземплярами класса.Например:

public class Car {
   static String name;
   public Car(String name) {
      this.name = name;
   }
}

...

Car a = new Car("Volkswagen");
System.out.println(a.name); // Produces Volkswagen

Car b = new Car("Mercedes");
System.out.println(b.name); // Produces Mercedes
System.out.println(a.name); // Produces Mercedes
2 голосов
/ 23 февраля 2011

Подумай об этом. Вы можете сделать это с помощью своего кода:

A a = new A();
A b = new A(); // Wrong... x is already initialised

Правильные способы инициализации x:

public class A 
{    
    private static final int x = 5;
}

или

public class A 
{    
    private static final int x;

    static
    {
        x = 5;
    }
}
0 голосов
/ 05 апреля 2018
    public class StaticFinalExample {
  /*
   * Static final fields should be initialized either in
   * static blocks or at the time of declaration only
   * Reason : They variables are like the utility fields which should be accessible
   * before object creation only once.
   */
  static final int x;

  /*
   * Final variables shuould be initialized either at the time of declaration or
   * in initialization block or constructor only as they are not accessible in static block
   */
  final int y;

  /*
   * Static variables can be initialized either at the time of declaration or
   * in initialization or constructor or static block. Since the default value is given to the
   * static variables by compiler, so it depends on when you need the value
   * depending on that you can initialize the variable appropriately
   * An example of this is shown below in the main method
   */
  static int z;

  static {
    x = 20; // Correct
  }
  {
    y = 40; // Correct
  }
  StaticFinalExample() {
    z = 50; // Correct
  }
  public static void main (String args[]) {
    System.out.println("Before Initialization in Constructor" + z);   // It will print 0
    System.out.println("After Initializtion in Constructor" + new StaticFinalExample().z); // It will print 50
  }
}
...