Saturday, February 05, 2005

More fun with enum

The Enum<E extends Enum<E>> class is very special: only the compiler is able to create instances of classes which extends Enum. This prevents the creation of dynamic enumerations. But there is hope:

final MockControl control = MockClassControl.createControl(
        Enum.class,
        new Class[]{String.class, int.class},
        new Object{"Foo", 1});
final Enum mock = (Enum) control.getMock();

System.out.println("mock.name() = " + mock.name());
System.out.println("mock.ordinal() = " + mock.ordinal());

The magic of EasyMock and its class extension (using cglib under the hood) creates a Java proxy for Enum. Bytecode engineering to the rescue!

But do note that some methods associated with enumerations (such as values()) do not exist in the base class, Enum. They are synthesized by the compiler specific to each enumeration class.

2 comments:

David Kemp said...

It is also worth noting that enums can implement interfaces. e.g.

public enum Foo implements Bar {
...
}

I haven't had a chance to try your suggestion of using EasyMock to create a mock enum, but am wondering what happens when it gets passed to a switch statement?

Brian Oxley said...

The compiler doesn't like the switch statement. The EasyMock trick seems to be nothing more than a trick, thought-provoking, but not very useful.