A bafflement moment on enum  
Author Message
Roedy Green





PostPosted: 2005-12-22 21:20:00 Top

java-programmer, A bafflement moment on enum I have written enum code that works, but suddenly I had a sinking
feeling that it has no business working. I did a little disassembling
and sorted out the mystery.

let's say I create an enum with method next().

Then I override the next() method with custom code in the various
enum constants.

These methods live in anonymous inner classes of the enum (though
oddly they decompile as static).

Then I do something like this:

Breed d = Breed.DALMATIAN;
d.next();

How on earth does Java know to use DALMATIAN.next() rather than
Breed.next()?

The answer is that d contains a reference to the DALMATIAN inner class
that EXTENDS the Breed enum class as well as being an inner class of
it. So the next() method overrides the one in the Breed class.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.
 
Ingo R. Homann





PostPosted: 2005-12-22 21:31:00 Top

java-programmer >> A bafflement moment on enum Hi Roedy,

Roedy Green wrote:
> I have written enum code that works, but suddenly I had a sinking
> feeling that it has no business working. I did a little disassembling
> and sorted out the mystery.
>
> let's say I create an enum with method next().
>
> Then I override the next() method with custom code in the various
> enum constants.
>
> These methods live in anonymous inner classes of the enum (though
> oddly they decompile as static).
>
> Then I do something like this:
>
> Breed d = Breed.DALMATIAN;
> d.next();
>
> How on earth does Java know to use DALMATIAN.next() rather than
> Breed.next()?
>
> The answer is that d contains a reference to the DALMATIAN inner class
> that EXTENDS the Breed enum class as well as being an inner class of
> it. So the next() method overrides the one in the Breed class.

If I understand you correctly, this is the "normal" behaviour that has
nothing to do with enums but worked the same in Java 1.2 where there
were no enums:

class Breed
{

class DALMATIAN extends Breed
{

public void next()
{
System.out.println("DALMATIAN.next()");
}
}

public void next()
{
System.out.println("Breed.next()");
}
}

So, what is the problem about this?

Ciao,
Ingo

 
Roedy Green





PostPosted: 2005-12-22 22:50:00 Top

java-programmer >> A bafflement moment on enum On Thu, 22 Dec 2005 14:31:20 +0100, "Ingo R. Homann"
<email***@***.com> wrote, quoted or indirectly quoted someone who
said :

>So, what is the problem about this?

The problem was not realising that the inner classes for each enum
class EXTENDED the enum main class. If they didn't, how enums worked
would be quite mysterious.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.
 
 
Chris Smith





PostPosted: 2005-12-22 23:53:00 Top

java-programmer >> A bafflement moment on enum Roedy Green <email***@***.com> wrote:
> The problem was not realising that the inner classes for each enum
> class EXTENDED the enum main class. If they didn't, how enums worked
> would be quite mysterious.

This is, in any case, the obvious implementation. I'd be careful about
making an assertion about the LANGUAGE that this happens. It is
certainly true in the Sun reference implementation, and will probably be
true of any other implementation you happen to be working with, as well.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
 
Ingo R. Homann





PostPosted: 2005-12-23 19:20:00 Top

java-programmer >> A bafflement moment on enum Hi,

Chris Smith wrote:
>>The problem was not realising that the inner classes for each enum
>>class EXTENDED the enum main class. If they didn't, how enums worked
>>would be quite mysterious.
>
> This is, in any case, the obvious implementation. I'd be careful about
> making an assertion about the LANGUAGE that this happens....

IIRC, this behaviour is specified in the langspec.

I do not remember if the kind of implementation as *sub*class is
specified as well - that means i do not remember if
"Breed.DALMATIAN.getClass() != Breed.getClass()" is true - which should
be true if it is a *sub*class. But of course "Breed.DALMATIAN instanceof
Breed" must be true.

But independant of the welldefined behaviour: I cannot see any reason
(performance?) to implement enums not as subclasses...

Ciao,
Ingo

 
 
Chris Smith





PostPosted: 2005-12-23 22:40:00 Top

java-programmer >> A bafflement moment on enum Ingo R. Homann <email***@***.com> wrote:
> IIRC, this behaviour is specified in the langspec.
>

Yes, you're right. I should start reading the JLS more. Section 8.9
says:

"The optional class body of an enum constant implicitly defines an
anonymous class declaration (15.9.5) that extends the immediately
enclosing enum type."

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation