How can I require a generic parameter to be an enum that implements an interface?

JavaGenericsEnums

Java 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSboddView Question on Stackoverflow
Solution 1 - JavaMichael MyersView Answer on Stackoverflow
Solution 2 - JavaAlex MillerView Answer on Stackoverflow