I have a class that takes in two parameterized types and I want to have a method that returns a new instance of one of the types. This is the class:
public class StateMachine<S extends State, E extends StateObject> {
// State
protected ArrayMap<S, E> states;
protected E currentState;
protected Entity entity;
// Bits
private Builder builder = new Builder();
private int bitOffset;
private boolean firstState = false;
public StateMachine(Entity entity) {
this.entity = entity;
states = new ArrayMap<S, E>();
}
public E createState(S key) {
// State identifiers must also be taggable
assert (key instanceof Tag);
if (!firstState) {
firstState = true;
bitOffset = key.numStates();
}
E state = (E) new StateObject(entity);
state.bitOffset = bitOffset;
state.bits.set(((Tag) key).getIndex());
states.put(key, state);
return state;
}
// Remainder omitted....
}
As you can see, I want to create a state and return its value based on the parameterized type. Currently, I have an EntityState
class that extends StateObject
and have an EntityStateMachine
that extends StateMachine
with the parameters <StateIdentifier, EntityState>
. However, when I call createState
from the EntityStateMachine
, the returned value is not an EntityState
but rather a StateObject
.
How can I ensure that the returned value is casted to proper parameterized type?
Java pattern to deal with this is to store Class<E>
, and use its newInstance
method, as follows:
// Class<E> object will be used to create new instances
private final Class<E> stateClass;
// Users will pass the class to StateMachine's constructor
public StateMachine(Entity entity, Class<E> stateClass) {
this.entity = entity;
this.stateClass = stateClass;
states = new ArrayMap<S, E>();
}
Now you can create new state objects as follows:
E state = stateClass.newInstance(); // Only parameterless constructors are supported
state.setEntity(entity);
How can I ensure that the returned value is casted to proper parameterized type?
This is not the question you should ask. The real question is,
How can I create an instance of a type parameter?
And the answer, of course is, "no way". You need a workaround, these are some ideas:
Class<YourType>
so the instance can be created reflectively. YourType
. YourType
, define a method like newInstance
on it and use it as a factory of more objects of the same type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.