The following code compiles (and runs tests as expected) in Eclipse:
import java.util.EnumSet;
public class EnumTest {
static enum Cloneables implements Cloneable {
One, Two, Three;
}
public <T extends Cloneable> T getOne(Class enumType) {
EnumSet<? extends T> set = EnumSet.allOf(enumType);
return set.iterator().next();
}
}
However, compiling with either javac
(JDK 7) directly or via Maven fails with the following error:
type argument ? extends T is not within bounds of type-variable E
To be honest, the complexity of enums + interfaces + type-parameters (generics) all at play at once threw me off as I was writing the code, but I thought I had finally gotten it right.
The goal is to write calling code like this:
Cloneable something = enumTest.getOne(Cloneables.class);
For example, in Eclipse the following test compiles and passes:
@Test
public void testGetFirst() {
assertSame(Cloneables.One, getOne(Cloneables.class));
}
Any clues about which is "correct," Eclipse or javac, are appreciated.
Also appreciated is any advice about alternate ways to implement the idea: take a class as a method param that can be used in EnumSet.allOf()
and that also determines the type of Enum objects in the EnumSet
By the way, don't bother critiquing the purpose of this method; I've reduced it down from more useful/meaningful code. I'm not interested in discussing the merits of "finding the first element from an enum type" - that's not the point of this question.
You need to make sure that T
is an enum type, or it won't meet the constraints for EnumSet
:
public <T extends Enum<T> & Cloneable> T getOne(Class enumType)
Also, you don't need the wildcard in your EnumSet
, and you shouldn't use the raw Class
type:
public <T extends Enum<T> & Cloneable> T getOne(Class<T> enumType) {
EnumSet<T> set = EnumSet.allOf(enumType);
return set.iterator().next();
}
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