I have a method that needs to accept a Enum class. These enums implement an interface. Now I need access to both Enum methods like ordinal(), name(), etc and my interface methods. What I've tried:
public <T extends ConfigFeature, Enum> void showEnabledFeatures(Class<T> enumType, long mask) {
List<T> list = Arrays.asList(enumType.getEnumConstants());
list.forEach(item -> {
// My interface's method, works fine
item.getMask();
// Enum method doesn't work:
// item.ordinal();
});
}
Reversing the order reverses the working:
public <T extends Enum, ConfigFeature> void showEnabledFeatures(Class<T> enumType, long mask) {
List<T> list = Arrays.asList(enumType.getEnumConstants());
list.forEach(item -> {
// My interface's method, doesn't work now
// item.getMask();
// Enum method now works:
item.ordinal();
});
}
Is there a way to get access to both methods from interface and Enum?
You are using the wrong syntax to say that T
must implement this interface AND is an enum.
This:
<T extends ConfigFeature, Enum>
is not constraining T
to Enum
, but actually creating a new generic parameter called Enum
.
Similarly,
<T extends Enum, ConfigFeature>
is not constraining T
to ConfigFeature
. You are declaring a new generic parameter called ConfigFeature
.
The correct syntax is to use &
:
<T extends Enum<T> & ConfigFeature>
Note that the order is actually important here! Enum
can only come first.
According to here, only the first constraint can be a class, and then the ones after it must all be interfaces:
TypeParameter:
{TypeParameterModifier} Identifier [TypeBound]
TypeParameterModifier:
Annotation
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
AdditionalBound:
& InterfaceType