Подтвердить что ты не робот

Почему конструктор перечисления не может получить доступ к статическому полю

Возможный дубликат:
Почему cant enums конструктор не может получить доступ к статическим полям?

enum Test {
  e1,e2;      

  int i=0;
  static int j=5;

  Test(){
    System.out.println(i+" "+j);
  }
}

В приведенном выше коде конструктор может получить доступ к переменной экземпляра, но не к статической переменной J.

Я прочитал ответ, относящийся к другому автору, все говорят, что e1 и e2 инициализированы до инициализации J (статическое поле), но согласно java spec все статическое поле инициализируется когда-либо класс, загруженный в память, то есть перед запуском конструктора. Поэтому перед запуском конструктора Test() статическая переменная j должна быть инициализирована. Я не могу понять ограничения, может ли кто-нибудь из вас заставить меня понять. Я уже прочитал ответ на вопросы Почему не может перечислить конструктор для доступа к статическим полям? Я не доволен ответом: "Конструктор вызывается до того, как все статические поля были инициализированы.

Предположим, если взять еще один пример с простым классом, например enum

class Test{
  public static final Test t=new Test();
  static int a=5;

  Test(){
    System.out.println(a);  
  }

  public static void main(String[] args) {
  }
}

Здесь, согласно аргументу, конструктор будет работать до инициализации статического поля, и он работает также при печати 0 (как JVM выполнил инициализацию). Но не ошибка компиляции или отсутствие проблемы времени выполнения. Тогда почему то же самое не происходит с перечислением.

4b9b3361

Ответ 1

Если вы представляете, как ваш enum действительно будет выглядеть как класс, это имеет смысл:

public class Test {
  // Imagine you cannot move these two statements:
  public static final Test e1 = new Test();
  public static final Test e2 = new Test();

  int i=0;
  static int j=5;

  private Test(){
    System.out.println(i+ " " + j);
  }

  static int getJ() {
    return j;
  }


  public static void main(String[] args) {
    System.out.println(Test.getJ());
  }
}

Отпечатки:

0 0
0 0
5

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

Ответ 2

Проблема в том, что экземпляры перечисления создаются во время инициализации статических полей. И они были созданы до инициализации ваших статических полей. Они должны быть в значениях статического массива и статически доступны, поэтому это имеет смысл. И как указано в anser: "Почему не может перечислить конструктор для доступа к статическим полям?", Его, к сожалению, это происходит до того, как все пользовательские статичные поля вводятся. Но если бы он был заменен, вы не могли бы использовать экземпляры enum в статической инициализации, поэтому ему понадобилось бы позволить статический блок как до, так и после создания значений перечисления.

Я не знаю, связана ли проблема с тем, что inicialization значений enum относится к классу Enum (и обрабатывается специалистом JVM (эта логика не относится к классу Enum), или потому, что вы не можете статически статические поля перед значениями перечисления.

ПОЧЕМУ так это может ответить лишь немногим людям (например, Джошу Блоху и Нилу Гафтеру, которые заявлены в качестве авторов Enum в javadoc и, возможно, некоторые неизвестные другие)