Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: Yaron LeviОтветов: 7
public class A
{
    private static final int x;

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

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

javaconstructorfinalstatic

Ответы

Ответ 1 · рейтинг 190 · adarshr

Конструктор будет вызываться каждый раз при создании экземпляра класса. Таким образом, приведенный выше код означает, что значение 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 обычно используется для доступа к общему ресурсу.

Поле делается статическим, но не окончательным; вместо этого при доступе к полю код проверяет, было ли оно уже инициализировано, если нет, то это делается тут же. Обратите внимание, что в средах с несколькими потоками вам необходимо синхронизировать доступ к полю, чтобы избежать доступа к нему во время его инициализации.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы