views:

592

answers:

2

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!

+13  A: 

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

Michael Myers
skaffman
I tend to agree (I think I've used it maybe once or twice, if that). But in the case of enums implementing an interface, I think it is appropriate.
Michael Myers
Excellent! That's exactly what I was looking for. Thanks muchly!
Sbodd
+1  A: 

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.

Alex Miller
Neat. Hopefully java 7 will appear before my beard goes grey.
skaffman
From writing a small amount of code that uses this stuff, my impression is that it's a little weird. Can't say I've seen it anywhere else. Something with a 7 in the name will release in 2010 I'm pretty sure. Whether it will be "Java 7" as endorsed by the JCP, I don't know. Only Oracle can answer that now...
Alex Miller