Конструктор будет вызываться каждый раз при создании экземпляра класса. Таким образом, приведенный выше код означает, что значение x будет повторно инициализироваться каждый раз при создании экземпляра. Но поскольку переменная объявлена окончательной (и статической), вы можете сделать это только
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;
}
}
Ответ 2 · рейтинг 17 · Sean Patrick Floyd
статические конечные переменные инициализируются при загрузке класса. Конструктор может быть вызван намного позже или вообще не вызываться. Кроме того, конструктор будет вызываться несколько раз (с каждым новым объектом), поэтому поле уже не может быть окончательным.
Если вам нужна пользовательская логика для инициализации вашего статического конечного поля, поместите ее в статический блок.
Ответ 3 · рейтинг 6 · rfeak
Подумайте о том, что происходит, когда вы создаете экземпляр объекта во второй раз. Он пытается установить его СНОВА, что категорически запрещено, поскольку является статическим финалом. Его можно установить только один раз для всего класса, а не экземпляра.
Вы должны установить значение, когда объявляете его
private static final x=5;
Если вам нужна дополнительная логика или более сложная реализация, это можно сделать в статическом блоке инициализатора.
Ответ 4 · рейтинг 5 · ap2cu
static означает, что переменная уникальна в приложении. final означает, что он должен быть установлен только один раз.
Если вы установите его в своем конструкторе, вы позволите установить переменную более одного раза.
Следовательно, вы должны инициализировать его напрямую или предложить статический метод для его инициализации.
Ответ 5 · рейтинг 3 · i.am.michiel
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
Ответ 6 · рейтинг 2 · Lukas Eder
Подумай об этом. Вы можете сделать это с помощью своего кода:
A a = new A();
A b = new A(); // Wrong... x is already initialised
Правильные способы инициализации x:
public class A
{
private static final int x = 5;
}
or
public class A
{
private static final int x;
static
{
x = 5;
}
}
Ответ 7 · рейтинг 1 · SQB
Статический
Ключевое слово static означает, что член объекта, в данном случае поле, не привязан к экземпляру класса, а вместо этого является членом класса. Если статический член является полем, он инициализируется во время загрузки класса.
Он доступен через класс, а не через экземпляр (хотя последнее не невозможно, это считается дурным тоном), поэтому он доступен без запуска конструктора вообще - никогда.
Финал
Ключевое слово final, примененное к полю объекта, означает, что оно может быть назначено только один раз и что оно должно быть назначено во время инициализации.
Статический финал
Взятые вместе, эти два ключевых слова эффективно определяют константу: она может быть назначена только один раз, должна быть назначена и одинакова для всех экземпляров этого класса.
Поскольку статическое поле инициализируется во время загрузки класса, оно должно быть инициализировано либо при объявлении, либо в блоке статического инициализатора.
Это означает, что если и когда вы дойдете до конструктора, он уже будет инициализирован, потому что он должен уже быть инициализирован.
Синглтон
Если вы ищете члена класса, которому назначаете только один раз, но читаете много раз, вы имеете дело с одиночка. Шаблон singleton обычно используется для доступа к общему ресурсу.
Поле делается статическим, но не окончательным; вместо этого при доступе к полю код проверяет, было ли оно уже инициализировано, если нет, то это делается тут же. Обратите внимание, что в средах с несколькими потоками вам необходимо синхронизировать доступ к полю, чтобы избежать доступа к нему во время его инициализации.