Google
 
Web unafbapune.blogspot.com

Saturday, July 12, 2008

 

Java Enum Puzzler

What does the following print ?
public enum FooEnum {
FOO { @Override public void bar() {} };
public abstract void bar();

public static void main(String...args) {
System.out.println(FOO.getClass().isEnum());
}
}
Answer:

FOO is an enum value in FooEnum. The class of FOO must therefore be an enum, and it should print "true". Right ? If you give it a try, surprisingly it will print "false". Why ?

Peeking into the JDK source code of Class.java,
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
// the ENUM bit set; classes for specialized enum constants
// don't do the former.
return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
Now if you tried to print out the super class of FOO.class, it would print FooEnum.class, rather than Enum.class. The comparison of the super class of FOO.class against Enum.class would therefore fail in the second condition of the return statement.

To me, this looks like a bug either in the javac compiler, or in the implementation of Class.isEnum().

Why is it probably a bug in the javac compiler ? Well, shouldn't the super class of FOO.class be Enum.class, instead of FooEnum.class ? (Special thanks to Dhanji R. Prasanna for pointing this out.)

Why is it probably a bug in Class.isEnum() ? Well, shouldn't it recursively check all the super classes of FOO.class for Enum.class, instead of just the direct super class ? And why does it need to compare the super class with Enum.class at all, when there is already the checking for the ENUM class modifier ?

What do you think ?

Update on 7/13/2008: Please vote for bug 6710708.

Comments:
The class of FOO is not an Enum type. The JLS (3e 8.9, pg 250) states that the "optional class body of an enum constant implicitly defines an anonymous class declaration that extends the immediately enclosing Enum type".

So FOO.class has FooEnum as its superclass.

FOO.class is not itself an Enum type and so Class.isEnum returns false.

What is missing is a method Class.isEnumConstant() which would check if the superclass is an Enum type. See the (closed) bug 6708424.

Cheers,
David
 
Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?