Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why enum constructor can't access static field [duplicate]

Tags:

java

enums

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.

like image 783
Krushna Avatar asked Nov 23 '12 07:11

Krushna


People also ask

Can enum have static fields?

The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.

Can you use enum in constructor?

The constructor takes a string value as a parameter and assigns value to the variable pizzaSize . Since the constructor is private , we cannot access it from outside the class. However, we can use enum constants to call the constructor.

Are enum fields static in Java?

Unlike a regular java class, you cannot access a non-final static field from an enum's constructor. What is the logic for creating this restriction in Java programming language? All enum constants (i.e. DOG, CAT and FISH in this case) are implicitly public, static and final.

Why is enum constructor private?

We need the enum constructor to be private because enums define a finite set of values (SMALL, MEDIUM, LARGE). If the constructor was public, people could potentially create more value. (for example, invalid/undeclared values such as ANYSIZE, YOURSIZE, etc.). Enum in Java contains fixed constant values.


2 Answers

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.

like image 89
Duncan Jones Avatar answered Oct 14 '22 05:10

Duncan Jones


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)

like image 32
Alpedar Avatar answered Oct 14 '22 05:10

Alpedar