it-roy-ru.com

Инициализировать статическое конечное поле в конструкторе

public class A 
{    
    private static final int x;

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

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

79
Yaron Levi

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

class A {    
    private static final int x;

    static {
        x = 5;
    }
}

Но, если вы удалите статические, вы можете сделать это:

class A {    
    private final int x;

    public A() {
        x = 5;
    }
}

Или это:

class A {    
    private final int x;

    {
        x = 5;
    }
}
169
adarshr

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

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

16
Sean Patrick Floyd

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

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

private static final x=5;

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

6
rfeak

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

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

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

5
ap2cu

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
3
i.am.michiel

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

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;
    }
}
2
Lukas Eder
    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
  }
}
0
Kush