wood burning stoves 2.0*
The moose likes Java in General and the fly likes enums do not allow access to static members within constructors and instance init blocks Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "enums do not allow access to static members within constructors and instance init blocks" Watch "enums do not allow access to static members within constructors and instance init blocks" New topic
Author

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

Hemant Murthy
Greenhorn

Joined: Jan 28, 2010
Posts: 5
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

Joined: Oct 27, 2005
Posts: 19653
    
  18

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.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

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.


[Jess in Action][AskingGoodQuestions]
Hemant Murthy
Greenhorn

Joined: Jan 28, 2010
Posts: 5
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

Joined: Jan 28, 2010
Posts: 5
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
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: enums do not allow access to static members within constructors and instance init blocks
 
Similar Threads
Static Initializer Expression
Strange but legal enum code
enum constructor help
Enums (Is this the best way)?
enum constructors