Pawel
Pawel

Reputation: 1467

Enum and static variable in constructor

Access to static fields in enum constructor is forbidden by the compiler. The source code below works, it uses a static field:

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);
    }
}

Output:

Count: 2.

But the code below does not work despite there being very little difference:

public enum TrickyEnum
{
    TrickyEnum1, TrickyEnum2;

    static int count;

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

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

From my search, people usually claim that the problem is due to the order in which static fields are initialized. But first example works, so why do Java developers forbid the second example? It should also work.

Upvotes: 28

Views: 1175

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

The compiler allows a call to a static function, because it is not smart enough to prohibit it: the legitimacy of the call cannot be deduced without looking into the body of the incrementCount method.

The reason this is prohibited becomes clear when you run the following code:

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();
}

This prints

1
2
123

which is extremely confusing to a programmer reading your code: essentially, incrementCount does its modifications to the static field before it has been initialized.

Here is a demo of this code on ideone.

Upvotes: 23

Related Questions