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

Enum и статическая переменная в конструкторе

Доступ к статическим полям в конструкторе enum запрещен компилятором. Исходный код ниже работает, он использует статическое поле:

public enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count;

    TrickyEnum()
    {
        incrementCount();
    }

    private static void incrementCount()
    {
        count++;
    }

    public static void main(String... args)
    {
        System.out.println("Count: " + count);
    }
}

Вывод:

Количество: 2.

Но приведенный ниже код не работает, несмотря на небольшую разницу:

public enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count;

    TrickyEnum()
    {
        count++; //compiler error
    }

    public static void main(String... args)
    {
        System.out.println("Count: " + count);
    }
}

Из моего поиска люди обычно утверждают, что проблема связана с порядком инициализации статических полей. Но первый пример работает, так почему разработчики Java запрещают второй пример? Он также должен работать.

4b9b3361

Ответ 1

Компилятор разрешает вызов статической функции, потому что он недостаточно умен, чтобы запретить его: легитимность вызова не может быть выведена, не глядя в тело метода incrementCount.

Причина, по которой это запрещено, становится понятным при запуске следующего кода:

enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count = 123; // Added an initial value

    TrickyEnum()
    {
        incrementCount();
    }

    private static void incrementCount()
    {
        count++;
        System.out.println("Count: " + count);
    }

    public static void showCount()
    {
        System.out.println("Count: " + count);
    }
}

public static void main (String[] args) throws java.lang.Exception
{
    TrickyEnum te = TrickyEnum.TrickyEnum1;
    TrickyEnum.showCount();
}

Отпечатает

1
2
123

что крайне запутывает программиста, читающего ваш код: по существу, incrementCount выполняет свои модификации в статическом поле до его инициализации.

Вот демон этого кода на ideone.