28

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.

Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
Pawel
  • 1,457
  • 1
  • 11
  • 22
  • Why would you use this counter ? – Christophe Roussy Dec 10 '13 at 15:39
  • 4
    It is only example for me to better know the java. Correct way is incremenenting static counter in static block or do not create this. It is redundant, enum elements can be counted, but I want to understand what is going on it this code. – Pawel Dec 10 '13 at 15:44
  • This is an interesting case indeed. – Christophe Roussy Dec 10 '13 at 15:56
  • possible duplicate of [Why enum constructor can't access static field](http://stackoverflow.com/questions/13524996/why-enum-constructor-cant-access-static-field) – Mikhail Dec 16 '13 at 08:45

1 Answers1

23

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523