Hi....I have started preparing for SCJP 6 from k & b... book. I have done the 1st chapter and give the self test and found one problem in question no. 4.
The question is :
Given:
1. enum Animals {
2. DOG("woof"), CAT("meow"), FISH("burble");
3. String sound;
4. Animals(String s) { sound = s; }
5. }
6. class TestEnum {
7. static Animals a;
8. public static void main (String[] args) {
9. System.out.println(a.DOG.sound + " " + a.FISH.sound);
10. }
11. }
What is the result?
And the answer is:
woof burble
I did not understand the concept of using " static Animals a; ". Anyone please help me.
Hi Rohit,
The point of that line is to declare a reference that can be used in a static method such as main()
The usage of a.DOG.sound and a.FISH.sound in line 9 are references via the class of a to the public instance variable sound of the enum instances, they could equivalently have been written as Animals.DOG.sound and Animals.FISH.sound and with line 7 commented out
Rohit Sidana wrote:Hi....I have started preparing for SCJP 6 from k & b... book. I have done the 1st chapter and give the self test and found one problem in question no. 4.
The question is :
Given:
What is the result?
And the answer is:
woof burble
I did not understand the concept of using " static Animals a; ". Anyone please help me.
Hi Rohit Sidana,
Here what happening in your code is :
The 'enum Animals' have three values namely DOG, CAT, FISH . Generally , the simple enum looks like 'enum Animals{DOG,CAT,FISH}'. But, like classes , enums also can have instance variables,constructors and methods . your code is showing the second type.
Now , in your code , the elements of enum Animals (DOG,CAT and FISH) are actually treated as instances of Animals. Here, since these instances are supplied with values (one for each) , the constructor is invoked automatically for each one. So, for instance , consider DOG("woof") . here on processing of DOG , constructor Animals("woof") is automatically executed and now Animals.DOG.sound gives "woof" .
In your code, there is a 'static Animals a ;' declaration . since we are accessing 'a' from static context (static main) , we declare it as static. So, as i said above, if you print the value of 'a.DOG.sound', it shows 'woof' on the screen.Similarly happens for a.FISH.sound, which prints burble.
I hope this gives you clear understanding..............
This confused me, too, so I did some reading. Here's what I learned: enum constants are implicitly static. As we know, Java allows you to access a static field with an instance reference. But it doesn't matter if the instance is null because the static field belongs to the type, not the instance.
Dennis Deems wrote:This confused me, too, so I did some reading. Here's what I learned: enum constants are implicitly static. As we know, Java allows you to access a static field with an instance reference. But it doesn't matter if the instance is null because the static field belongs to the type, not the instance.
To add to Dennis' reply, the compiler substitutes a.DOG.sound with Animals.DOG.sound as it considers DOG as a static object belonging to the Animals class. So, the JVM would not be able to see a.DOG.sound. Hence, a being null is immaterial in this case and the NullPointerException would not be thrown.
So I just take it as a rule then; enum's can never throw NullPointerExceptions ! (since they are not considered objects (?)).
Hi Mehmet,
CAT, DOG and FISH are all (implicitly static) objects of enum type Animals. So, we can't say enums are not considered objects.
We can also get a NullPointerException in cases like the one below wherein we are trying to use the instance method getSound() using a null reference a.
I just searched for every occurrence of the word 'enum' in the java spec 3.0, but I'm not very good at reading the java specs, and I couldn't find a rule for that behavior.
So I'm still confused.
I get your point with the instance method getSound().
Your explanation clarifies it best :
the compiler substitutes a.DOG.sound with Animals.DOG.sound as it considers DOG as a static object belonging to the Animals class. So, the JVM would not be able to see a.DOG.sound. Hence, a being null is immaterial in this case and the NullPointerException would not be thrown.
IMHO they should have prevented the invocation of static methods / fields over a reference, like in C#.
We just need to memorize that the compiler replaces refToClassA.staticVar and refToClassA.staticMeth() with ClassA.staticVar and ClassA.staticMeth() respectively.