• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

enums do not allow access to static members within constructors and instance init blocks

 
Hemant Murthy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everyone..
This is my first post on this forum. And I'm being nice (I hope) as per agreement

Had a question on enums. I'm using Java 1.6.

Is there any specific reason why enums don't allow access to static member variables within instance initialization blocks or enum constructors?

For example, see some sample code below. The first uses the usual enum, and includes a static and instance init block. The second uses a class to simulate an enum. Both are functionally similary. However, The class version allows access to j (a static member variable) within instance init block and contructor, but the enum version gives a compiler error "Cannot refer to the static enum field UsualEnum.j within an initializer".

Usual Enum ...


Enum simulated using a class ...


The output of the second version is ...
Instance Init Block of MyEnum
j = 1
Instance Init Block of MyEnum
j = 2
Instance Init Block of MyEnum
j = 3
Instance Init Block of MyEnum
j = 4
Static Init Block of MyEnum, j = 4
VALUE01
VALUE02
VALUE03
VALUE04



Another thing...
In the class version of the above (second one), if I change ...

to


the output changes to
Instance Init Block of MyEnum
j = 1
Instance Init Block of MyEnum
j = 2
Instance Init Block of MyEnum
j = 3
Instance Init Block of MyEnum
j = 4
Static Init Block of MyEnum, j = 0
VALUE01
VALUE02
VALUE03
VALUE04


After four inits, j becomes 0 now. I understand all static blocks run first, including static variable initialisations, in the order that they appear in code. But why reset j to 0? Isn't this initialized when space for static j is created? Looking at this output, it seems that the statement has been split into two: static int j; which runs before any init blocks execute, and a j = 0; runs after the creation of the four static finals, as per the order they appear in code.

If I move the statement to before creating the four static finals, then the program gives the same output irrespective of whether I explicitly init j to 0 or not.

Do let me know. Thanks in advance.

Best regards,
Hamy
 
Rob Spoor
Sheriff
Pie
Posts: 20514
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Enum instances are created before any static initializer / block is executed. Therefore, j has no value yet. For some reason this is allowed in non-enums; possibly because in non-enum classes you can still switch the initializer order, while you cannot in enums.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It sounds like you actually understand what's happening already, but perhaps you just don't like it. When a class is being initialized, first all the statics get their default values; then all the initializers and static init blocks run, in order, top to bottom. I'm not sure why you think the initializer for "j" ought to run before the ones for VALUEXX, but obviously, it doesn't; it runs later.

There's definitely a lesson here: be careful not to access member variables (static or instance) before they're initialized; it's surprisingly easy to do by mistake.
 
Hemant Murthy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm... Sounds right.
Thanks for your prompt reply mate.

Then what about the second question regarding the static variable j being reset to 0?

If j was already initialised (as the value of j increments after every init block executes), why does it get reset to 0? (ok I think I know why, but why TWICE ?). The behavior is more prominent if I change the statement to
private static int j = 1;
The output is ...
Instance Init Block of MyEnum
j = 1
Instance Init Block of MyEnum
j = 2
Instance Init Block of MyEnum
j = 3
Instance Init Block of MyEnum
j = 4
Static Init Block of MyEnum, j = 1
VALUE01
VALUE02
VALUE03
VALUE04


So j is first 0 before creating any static finals, then after all inits it's 4, and the it gets reset to 1. So is this what the behavior is supposed to be, that the variable first gets initialised to it's default, and then, based on the order of statements, will get initialised to the value coded by you?

- Hamy
 
Hemant Murthy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oops. Read Earnest's reply AFTER I submitted my previous one (in much earnest).
Sounds good. Yes, need to be careful with these static inits and stuff.

BTW, guys, wish me luck. My SCJP 1.6 exams up tomorrow.
Rgds,
Hamy
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic