enums and modifiers

R

richnjones

Hello all,

I was messing around with enums and am confused about the modifiers I
can apply. I am using Eclipse and am not sure if I am misunderstanding
the error.

Consider this enum

enum Planets {Mercury, Venus}

I can put private/protected/public in front of it. At the moment I
consider it to have package access. This makes perfect sense

I can also add static in front of it. Enum is a class that extends
Object so that kind of makes sense. However I cannot add final in
front of it. Now I dont believe you can extends enums (why would you
want to) so having final might seem a little pointless but i do not
see why you cannot have it for completeness. (You can add final to
variables in Iiterfaces which are implicitly final) Also and more
confusingly when I put final in front of it then Eclipse says it is an
invalid modifier and that I can only have private/protected/public/
abstract/static. When I put abstract in front I get a compile error.
Is Eclipse wrong? Can you put an abstract in front of enums in some
cases? Is there any reason you cannot put final in front? (Assuming
you can use abstract then i can see why final isnt allowed). What use
would an abstract have?

abstract enum Planet {Mercury, Venus} //does not compile

Any help is greatly appreciated
Thanks
R
 
R

richnjones

ah so the Enum class is abstract. This I believe is what the compiler
uses when it come across the enum keyword. That would explain why I
cannot use final. Is the fact that the class is abstract confusing
Eclipse which tells me I can use abstract?
 
J

Joshua Cranmer

I can put private/protected/public in front of it. At the moment I
consider it to have package access. This makes perfect sense

Only if it is internal to a class. Top-level source declarations can
only have a package-protected or public access level, same as classes,
interfaces, and annotations.
I can also add static in front of it. Enum is a class that extends
Object so that kind of makes sense.

Once again, only if internal to a class.
> However I cannot add final in
front of it. Now I dont believe you can extends enums (why would you
want to) so having final might seem a little pointless but i do not
see why you cannot have it for completeness. (You can add final to
variables in Iiterfaces which are implicitly final)

enums != interfaces.
The short answer: enums have nuanced finality/abstractness qualifiers.
Specifically, an enum of the sort:
enum Foo {
ONE {
public boolean getVar() { return true; }
}, TWO {
public boolean getVar() { return false; }
}

public abstract boolean getVar();
}

is actually composed with three classes internally (Foo, Foo$ONE, and
Foo$TWO) of which the first one is abstract and the other two are not.
Since an enum can actually be abstract in some cases and final in
others, neither qualifier is valid. See the JLS for more information.
> Also and more
confusingly when I put final in front of it then Eclipse says it is an
invalid modifier and that I can only have private/protected/public/
abstract/static. When I put abstract in front I get a compile error.

See above.
Is Eclipse wrong? Can you put an abstract in front of enums in some
cases? Is there any reason you cannot put final in front? (Assuming
you can use abstract then i can see why final isnt allowed). What use
would an abstract have?

No, Eclipse is not wrong; it follows the JLS precisely in this instance.

JLS 3 §8.9 Enums:
Enum types (§8.9) must not be declared abstract; doing so will result in
a compile-time error. It is a compile-time error for an enum type E to
have an abstract method m as a member unless E has one or more enum
constants, and all of E's enum constants have class bodies that provide
concrete implementations of m. It is a compile-time error for the class
body of an enum constant to declare an abstract method.

An enum type is implicitly final unless it contains at least one enum
constant that has a class body. In any case, it is a compile-time error
to explicitly declare an enum type to be final.

Nested enum types are implicitly static. It is permissable to explicitly
declare a nested enum type to be static.

Those are the full rules for modifiers attached to enums.
 
L

Lew

ah so the Enum class is abstract. This I believe is what the compiler
uses when it come across the enum keyword. That would explain why I
cannot use final. Is the fact that the class is abstract confusing
Eclipse which tells me I can use abstract?

Don't know what's up with Eclipse, but the JLS clearly states:
Enum types (§8.9) must not be declared abstract;
doing so will result in a compile-time error.
and
An enum type is implicitly final
unless it contains at least one enum constant that has a class body.
In any case, it is a compile-time error to explicitly declare an enum type to be final.
Also,
Nested enum types are implicitly static.
It is permissable to explicitly declare a nested enum type to be static.

There are more restrictions, too.
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9>

It's not to do with the implementation of enums as extension of Enum, rather,
with the language's laws.
 
R

richnjones

Hi Lew and Joshua,

Thanks for the replies. It is much clearer now. I am studying for my
SCJP and there is nothing like messing around with code to make you
confused. Thanks again

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top