I’ve been working with Java 5 Generics for about one year now and one pattern that emerged from my experience is the use of generics to create enumerations that provide type safety (I don’t claim to be the inventor of that pattern, actually I don’t even claim it is a pattern).

Often type safety can be achieved by using method type variables like

public abstract <N extends Number> createNumber(
	Class<? extends N> numberType,
	String stringValue);

The drawback of this solution is that all the classes must belong to the same hierarchy, in that example they all need to be a subclass of java.lang.Number. The most direct workaround is to free the type variable from its upper bound java.lang.Number. That makes the choice very large since any subclass of java.lang.Object can be accepted.

It is also impossible to prevent some subclass to be used as type argument at compilation time. Failure would have to happen at runtime with an java.lang.IllegalArgumentException thrown for instance.

Those two limitations makes the method not easy to understand the first time you see it, specially when it is part of an API, and it is not possible to make it type safe (actually not as far as I know :-) ) as Java Enums cannot be used as a generic declaration.

So I had to find a way to express an enumerated type that would be type safe. The solution I found is actually not an enumeration in the old/classic way we use to know it before Java 5 Enums (i.e it is class that has a private constructor with public static fields) and therefore it cannot be used in a switch statement. That probably is the only drawback I found but it is a more acceptable issue than the two problems I had before.

Let’s assume we represent a concept of simple types which are arbitrarily defined by String, Boolean and Integer with

public class SimpleType<S> {

   public static final SimpleType<String> STRING =
      new SimpleType<String>(String.class);

   public static final SimpleType<Integer> INTEGER =
      new SimpleType<Integer>(Integer.class);

   public static final SimpleType<Boolean> BOOLEAN =
      new SimpleType<Boolean>(Boolean.class);

   private final Class<S> javaType;

   private SimpleType(Class<S> javaType) {
      this.javaType = javaType;
   }
}

Now we can easily use it as a type safe enumeration, for instance here is how I would write a parse method:

/*
 * Note : yeah this is not really OO and it could be
 * possible to have an abstract parse(String s)
 * method on the SimpleType class and have the static
 * method delegate to it. I leave it as an exercise
 * for the reader.
 */
public <T> T parse(SimpleType<T> simpleType, String s) throws NullPointerException {
   if (simpleType == null)
      throw new NullPointerException("No null simple type is accepted!");
   if (s == null)
      throw new NullPointerException("No null string can be parsed!");
   if (simpleType == SimpleType.STRING)
      return s;
   if (simpleType == SimpleType.INTEGER)
      return Integer.valueOf(s);
   if (simpleType == SimpleType.BOOLEAN)
      return Boolean.valueOf(s);
   throw new AssertionError("impossible!);
}

This way we enforce the set of types that can be passed as arguments in our method and we do it in a manner that will enforce the developer to write type safe code.

Next time I’ll show you have it is possible to improve the pattern efficiency and usability by adding methods on the Type Safe Enumeration class.



blog comments powered by Disqus

Published

28 July 2009