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?
Source: Tips4all, CCNA FINAL EXAM
Don't use a generics bound. There's no need. Just use an unbounded type, like this:
ReplyDeletepublic class State<T> {
public State(T startState) {
// whatever
}
}
And to use it:
State<Days> dayState = new State<Days>(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<String>("hello");
because String is not an enum.
enums are final types, which means, you can not extend from them
ReplyDeletea 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
You cannot extend enums in java (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html towards the end). Thus is not possible.
ReplyDelete-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 ?
The thing to do here is
ReplyDeletepublic 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.
This compiles fine for me under Java 6:
ReplyDeletepublic 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);
// ...
}