19

Possible Duplicate:
Why can’t enum’s constructor access static fields?

enum Test {
  e1,e2;      

  int i=0;
  static int j=5;

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

In the above code the constructor can access the instance variable but not the static variable J.

I have read the answer relate to other author all are saying the e1 and e2 initialized before the initialization of J( static field), But according java spec all the static field initialized when ever the class loaded to memory, that is before running of the constructor. So before running of Test() constructor the static variable j must be initialized. I'm not able understand the restriction, can any body make me understand.I have already read the answer of the questions Why can't enum's constructor access static fields? But I am not happy with answer like :-The constructor is called before the static fields have all been initialized.

Suppose if take another example with a simple class like 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) {
  }
}

Here according to there argument the constructor will run before the initialization of static field and it's running also as it's print 0(As JVM did the initilization). But no compilation error or no run time problem. Then why the same thing not happen with enum.

Community
  • 1
  • 1
Krushna
  • 5,059
  • 5
  • 32
  • 49
  • 1
    Good question actually, I couldn't figure out why this is. Might have something to with how the Java-compiler compiles the class file. – Gerbrand Nov 23 '12 at 08:01
  • 1
    I'm not a java expert, but aren't the members of an enum (`e1` and `e2` above) essentially static members of the `enum`? And as such, when *they* are initialized with values, the constructor has to be invoked. But `j` won't have been initialized yet? – Damien_The_Unbeliever Nov 23 '12 at 08:25
  • Every enum in Java is *like* a class extending `java.lang.Enum`. This `java.lang.Enum` can't be extended by another other *normal* classes. So, your argument that "a simple class like enum" produces expected output is invalid. – Prasanth Nov 23 '12 at 08:54
  • [My answer to this other question](http://stackoverflow.com/questions/12447545/creating-a-final-java-class-array-of-enum-constants-with-values/12448187#12448187) might help shed some more light on this. – Ian Roberts Nov 23 '12 at 09:39
  • @ Damien_The_Unbeliever Yes the e1 and e2 are public static and final so to initialized constructor need to invoke, but if you test the same thing with a simple class as given you can see that before running of constructor the value of a initialize to 0 by JVM then what the problem, why the restriction for enum – Krushna Nov 23 '12 at 09:47

2 Answers2

6

If you imagine how your enum would actually look as a class, it makes sense:

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

This prints:

0 0
0 0
5

If you can share a concrete example (rather than a theoretical one), we could suggest how to redesign the code to achieve the desired result, despite the static field limitations.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
3

Problem is, that instances of enum are created during inicialization of static fields. And they created before initialization of your static fields. They must be in static array values and statically accessible, so it makes sense. And as stated in anser to "Why can't enum's constructor access static fields?", its unfortunate that this happens before all user defined static field inicialization. But if it was swapped, you could not acces enum instances in static initialization, so it would need allowing static block both before and after creation of enum values.

I don't know whether problem is because inicialization of enum values is concern of Enum class (and handled specialy by JVM (this logic is not in Enum class itself), or because you cannot put static fields before enum values.

WHY it is that way can answer only few people (eg. Josh Bloch and Neal Gafter who are stated as authors of Enum in javadoc, and maybe some unknown others)

Alpedar
  • 1,314
  • 1
  • 8
  • 12