Почему конструктор перечисления не может получить доступ к статическому полю
Возможный дубликат:
Почему 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 выполнил инициализацию). Но не ошибка компиляции или отсутствие проблемы времени выполнения. Тогда почему то же самое не происходит с перечислением.
Ответы
Ответ 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 и, возможно, некоторые неизвестные другие)