Синглтон через enum way является ленивым инициализированным?

Это очень распространенный синглтон-код enum:

public enum enumClazz{
   INSTANCE
   enumClazz(){
     //do something
   }
}

и множество мест сказали, что это ленивая инициализация. Но я запутался после того, как прочитал главу 7Внутри виртуальной машины Java » - Срок службы типа:

Спецификация виртуальной машины Java предоставляет реализациям гибкость во времени загрузки класса и интерфейса и связывания, но строго определяет время инициализации. Все реализации должны инициализировать каждый класс или интерфейс при первом активном использовании. Следующие шесть ситуаций квалифицируются как активные использования:

Создается новый экземпляр класса (в байт-кодах - выполнение новой инструкции. Альтернативно, через неявное создание, отражение, клонирование или десериализацию.)Вызов статического метода, объявленного классом (в байт-кодах - выполнение инструкции invokestatic)Использование или присвоение статического поля, объявленного классом или интерфейсом, за исключением статических полей, которые являются окончательными и инициализируются выражением константы во время компиляции (в байтовых кодах - выполнение инструкции gettatic или puttatic)Вызов определенных отражающих методов в Java API, таких как методы в классе Class или в классах в пакете java.lang.reflectИнициализация подкласса класса (Инициализация класса требует предварительной инициализации его суперкласса.)Обозначение класса в качестве исходного класса (с main () < метод), когда виртуальная машина Java запускается

Третий пункт жирным шрифтом уточнить, что если полеstatic final, инициализация поля происходит во время компиляции. Точно так жеINSTANCE вenumClazz неявно равноpublic static final и соблюдать третий пункт.

Может ли кто-то исправить меня, если мое понимание неверно?

Ответы на вопрос(2)

что если полестатический финал, инициализация поля происходит во время выполнения

Не совсем - это относится только кстатические поля, которые являются окончательнымии инициализируется константным выражением времени компиляции ":

static final String = "abc"; //compile time constant
static final Object = new Object(); //initialised at runtime

В вашем случае синглтон будет инициализирован при загрузке класса enum, то есть в первый разenumClazz упоминается в вашем коде.

Так что это фактически лениво, если, конечно, у вас нет кода где-то еще в вашем коде, который использует перечисление.

 Holger13 сент. 2018 г., 15:27
Заявление какClass c = EnumClazz.class; не запускает инициализациюEnumClazz, На самом деле, этоДовольно сложно запустить его инициализацию, фактически не используя его. Это'Стоит подчеркнуть, чтопогрузка а такжеинициализация это две разные вещи.
 vash_ace27 мая 2013 г., 17:09
Все очищено. Огромное спасибо :)
 assylias27 мая 2013 г., 17:06
Да это было бы лениво инициализировано таким же образом.
 vash_ace27 мая 2013 г., 16:44
class Singleton {public static final instance = new Singleton (); ...} Итак, для общего пути класса это 'пример' ленивый инициализируется?
Решение Вопроса

enum поля экземпляране "инициализируется константным выражением времени компиляции, Они могут'потому чтотолькоString и примитивные типы являются возможными типами для константного выражения во время компиляции.

Это означает, что класс будет инициализирован, когдаINSTANCE первый доступ (что является именно желаемым эффектом).

Исключение в полужирном тексте выше существует, потому что эти константы (static final поля, инициализированные постоянным выражением времени компиляции), будут эффективно встроены во время компиляции:

class A {
  public static final String FOO = "foo";

  static {
    System.out.println("initializing A");
  }
}

class B {
  public static void main(String[] args) {
    System.out.println(A.FOO);
  }
}

Выполнение урокаB в этом примере будетне инициализироватьA (и воляне Распечатать "инициализация А "). И если вы посмотрите на байт-код, сгенерированный дляB вы'увидим строковый литерал со значениемFoo» а такженет ссылка на класс.A

Ваш ответ на вопрос