How can I require a generic parameter to be an enum that implements an interface?
JavaGenericsEnumsJava Problem Overview
I'm not 100% convinced that this is a good idea, but I bumped into some code today that's currently implemented as:
class MyWidget <T extends Enum<T> > {
MyWidget(Map<T, Integer> valueMap) {
mValueMap = valueMap;
}
Map<T, Integer> mValueMap;
}
where MyWidget
then offers methods that use mValueMap
to convert the passed-in Enum
to/from an Integer
.
What I was considering doing was trying to refactor this, so that I'd declare my enumeration:
interface MyInterface {
public Integer getValue();
}
enum MyEnum implements MyInterface {
foo, bar;
public Integer getValue() {
return ordinal();
}
}
And I'd then be able to rewrite MyWidget
into something that looked vaguely like this:
public class MyWidget<T extends Enum<T> extends MyInterface> {
...
}
and would then be able to call the getValue()
method from MyInterface
on T
-type objects within MyWidget
. The problem, of course, is that "<T extends Enum<T> extends MyInterface>
" isn't valid syntax. Is there any way to pull this off?
I don't want to just have MyWidget<T extends MyInterface>
, because it's also important that T be an enumeration.
Thanks in advance!
Java Solutions
Solution 1 - Java
Use an '&
' instead:
public class MyWidget<T extends Enum<T> & MyInterface> {
...
}
The JLS calls this an "intersection type", but I can find no mention of it in the Java tutorials. I'll just say that it does exactly what you were wishing that "extends
" would do.
Also, I should mention that you can have as many types as you want in the intersection type. So if you wanted, you could do:
public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> {
...
}
[Note: this code sample should not be construed as an endorsement of the Cloneable
interface; it was merely handy at the time.]
Solution 2 - Java
The JSR 203 (new new IO) stuff for JDK 7 is making a lot of use of enums that implement interfaces (for example: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html) to allow them some wiggle room in the future for future additional sets of enum options. So that is a feasible approach and obviously one that was chosen after a lot of thought in one large Sun project.