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!
Yes, Enum implements an interface in Java, it can be useful when we need to implement some business logic that is tightly coupled with a discriminatory property of a given object or class.
However, it is possible to use enums in generics. The MSDN article for Enum gives the following type definition for the class Enum . This definition can be used to get enum s working as generic types by constraining the generic type to those of Enum .
To make it clearer, please see the following code: public interface Thing{ public enum Number{ one(1), two(2), three(3); private int value; private Number(int value) { this. value = value; } public int getValue(){ return value; } } public Number getNumber(); public void method2(); ... }
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.]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With