Reputation: 3247
I have an enum
public enum Days {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
I want to make a class which can take values of type Days. So I used Java Generics
public class State<T extend Days>
But there is an error
The type parameter T should not be bounded by the final type Days.
Final types cannot be further extended
How can I resolve this?
Upvotes: 16
Views: 12379
Reputation: 424983
Don't use a generics bound. There's no need. Just use an unbounded type, like this:
public class State<T> {
public State(T startState) {
// whatever
}
}
And to use it:
State<Days> dayState = new State<>(Days.SUNDAY);
This is a straightforward typed class that doesn't need a bound.
The only bound that might make sense is a bound to an enum
:
public class State<T extends Enum<T>> {
public State(T startState) {
// whatever
}
}
This version requires that the generic parameter be an enum
. With this version the above usage example would still compile, but this would not compile (for example):
State<String> dayState = new State<>("hello");
because String
is not an enum
.
Upvotes: 10
Reputation: 65803
This compiles fine for me under Java 6:
public enum Days {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
public class State<T extends Days> {
T state;
public State(T startState) {
this.state = startState;
}
}
private void test() {
State<Days> state = new State<Days> (Days.MONDAY);
}
However, if you want your State
object to change from one enum
to another you would be better to use something like:
public class State<S extends Enum<S>> {
final ArrayList<S> states = new ArrayList<S>();
private S state;
public State(S startState) {
states.addAll(EnumSet.allOf(startState.getClass()));
this.state = startState;
}
public S next() {
return state = states.get((state.ordinal() + 1) % states.size());
}
public S prev() {
return state = states.get((state.ordinal() - 1 + states.size()) % states.size());
}
public S set(S newState) {
return state = newState;
}
public S get() {
return state;
}
}
private void test() {
State<Days> state = new State<Days> (Days.MONDAY);
// ...
}
Upvotes: 2
Reputation: 198023
The thing to do here is
public enum Days{..}
public class State { // no generic argument!
...
}
As it stands, you can't have State<T extends Days>
because the only way to satisfy T extends Days
is to have T
be Days
. That's what it means for Days
to be final
.
So instead, you should make State
not generic, and use Days
directly everywhere you were trying to use T
. You can't declare public class State<Days>
, because then it'll try to treat Days
as a type variable, not as the class Days
, and that's not what you want.
Upvotes: 5
Reputation: 3289
enums are final types, which means, you can not extend from them
a generic like wants a Class as Parameter which is Days or an extended class, but the extended class is not possible
so the only parameter possible is Days and you don't need a generic, if only one value is possible
Upvotes: 9
Reputation: 543
You cannot extend enums in java (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html towards the end). Thus is not possible.
-IF you need your class to work only with your enum you don't need generics
-if instead you need it to work with others enum (does it makes sense?) you don't need to specify the extend.
What does exactly your State class do ?
Upvotes: 5