Tuesday, July 5, 2011

Extended Enums usage

Since the re-launch of extended enums I'm paying attention in my everyday coding (yes I still write code :) if extended enums will help me.
Here are 2 new examples:
1) I found out that most of the time the name() of the enum is not what I need. I need it to map an XML or HTML tag, an external ID, an entry name in excel or simple type name in a JSON object. So I write something like:

public enum ConfigName {

private final String xmlKey;

LdapConfig(String xmlKey) {
this.xmlKey = xmlKey;

public String getXmlKey() {
return xmlKey;

I could remove the getter, and the IDE helping a lot writing the boiler plate code but why? Here is how it should look:
    public enum ConfigName extends AlternateEnumKey {

The extra feature here is that the name() of the enum (ALL, INTERNAL, OR) is a constant that is not recognized as such by the javac compiler. So:
    @XmlTag(tag = ConfigName.ALL)

will not compile and so:
    @XmlTag(tag = ConfigName.ALL.xmlKey)

will for sure not.

But with extended enum you'll have:
    public @interface XmlTag { AlternateEnumKey tag(); }

// The framework managing XmlTag will take the alternate key value
@XmlTag(tag = ConfigName.ALL)

2) Since extended enums also supports generics for enums, and I just have this issue associating also a long (ID) to an enums, you can now write:
    public enum ConfigName extends EnumPairExtension<Long, String> {
ALL(45L, "local-all"),
INTERNAL(56L, "local-int"),
OR(98L, "local-int-ext");

assert ConfigName.OR.a == 98L;

With this, parsing definitions are a lot cleaner to write.

Tuesday, June 14, 2011

A new push for extended enums!

At Devoxx09, Joe Darcy presented the status and future of the Coin project, and how changes to the language are selected and implemented (or vice versa). :)
During his talk, he showed the cost classification of a language change: trivial, small, medium, big, or huge, and emphasized the fact that each change is also a benefit (hard to measure a priori) that can be estimated as big, medium, or small.
So for example, the new loop syntax introduced in Java5 was a small change with big benefits—a no "brainer", let's do it!

However, in his talk he showed how "Extended Enums" were at least medium cost with a small benefit.

I started working on "Extended Enums" (previously "abstract enum") since the release of OpenJDK and the launch of the now defunct KSL (Kitchen Sink Language) in 2006. From the amount of hits this blog is getting on "extended enums", I know this issue is of big concern for many Java developers.
I developed a working solution, but stopped pushing for it for two main reasons:
  • This addition to the language is a change to the Java-type system. Moreover, it cannot be a small modification; it is at least a medium change.
  • Looking at Scala Traits or Fantom Mixin, I had the feeling that it was pushing Java too much, and perhaps in the wrong direction.

So I talked with Joe Darcy at Devoxx09 about all the things I discovered implementing this change to the javac compiler (and other needed changes to the JDK classes). It was clear that the change is medium size, but I disagree that the benefits are small.
The benefits of "Extended enums" as implemented today:
  • Ability for enum declaration to extend an actual abstract class
    This is the evident benefit, and it is a small benefit. Using delegation and/or in-lined anonymous classes is not too verbose and provides the same benefits. Still it is nicer and cleaner to have the normal OO inheritance.
  • Ability to use Generics in Enum classes
    With "Extended enums" you can have code like this:

    public enum ActionQuery<T extends Action> {
    ALL<Action> {
    public List<Action> getResults() {...}
    EDIT_ACTION<EditAction> {
    public List<EditAction> getResults() {...}
    VIEW_ACTION<ViewAction> {
    public List<ViewAction> getResults() {...}
    public abstract List<T> getResults();

    I find "Extended enums" very useful in organizing SQL queries and their results, playing with properties and their types, and so on.
  • The most important feature and the reason why I developed "Extended enums" was to have the ability to define annotation enum parameters without having to specify their list of values in advance. You can already see this issue in today's JPA specification. There is an enum FetchType that is fixed in the spec to LAZY and EAGER, but Hibernate also supports SUBSELECT, which is approximately between LAZY and EAGER. To support SUBSELECT, you need to use the Hibernate specific annotation in combination with the standard one. If the FetchType was an abstract enum, the JPA specification does not need to enforce a well-defined list, but could have a proposed DefaultFetchType and let JPA implementation and application developers define a new enum with their desired list of FetchType. This already works great in the "abstract enum" implementation and provides me with great benefits in many other areas: (such as BindingType in JSR-299 Context and Dependency Injection, Cache declaration using enum instead of error prone string for region, Group in JSR-303 Bean Validation using user defined enums instead of empty interfaces, and more).

From my point of view (and I think/hope I'm not alone), Joe Darcy missed the benefit point of the extended enum. It is a big benefit to the Java language.
This was and is my position for some time. What pushed me to re-launch "Vote for Extended Enums for the Coin project!", is of course Christof May from soplets.org (which setup the extended-enums site: http://www.extended-enums.org/), and the fact that I found a way to make the change a "small" one. Until now, I was sure that to implement this correctly a new flag was needed in the class byte code, and many changes to the Java type management were necessary.

So, if you are interested or want to learn more please check the extended enums web site: http://www.extended-enums.org/