Reputation: 3008
I would like to know what is the right way to declare Class<...> stateBaseClass
, when my goal is to create an instance by using Reflection: state = stateBaseClass.newInstance();
without using cast.
I put some comments in the code below:
abstract class StateBase{} // It is so complex to be serializable.
class State extends StateBase{}
class StateInstanceDescription <T extends StateBase> implements Serializable{
private static final long serialVersionUID = -828114417567233018L;
transient private T stateBase;
// what is the right way to declare the line below to void that cast?
private Class<? extends StateBase> stateBaseClass;
public StateInstanceDescription(T base){
this.stateBase = base;
stateBaseClass = base.getClass();
}
public T getBase() {
return stateBase;
}
public Class<? extends StateBase> getBaseClass() {
return stateBaseClass;
}
}
public class Main {
public static void main(String ... args) throws InstantiationException, IllegalAccessException{
State state = new State();
StateInstanceDescription<State> stateInstDesc = new StateInstanceDescription<>(state);
// ... At some point, I will recreate State after deserialize stateInstDesc.
// compiler-time error. Compiler is asking for casting it to (State).
// There is a way to avoid this cast?
state = stateInstDesc.getBaseClass().newInstance();
}
}
Upvotes: 0
Views: 63
Reputation: 85779
getBaseClass()
returns a Class<? extends StateBase>
so the result of newInstace
can be any subclass of StateBase
(depending on the class returned). The compiler cannot be sure that this result is specifically of type State
or from another subclass.
To fix this, work with Class<T>
and pass this as argument to the constructor of StateInstanceDescription
:
class StateInstanceDescription <T extends StateBase> implements Serializable {
transient private T stateBase;
private Class<T> stateBaseClass;
public StateInstanceDescription(T base, Class<T> clazzBase) {
this.stateBase = base;
stateBaseClass = clazzBase;
}
public T getBase() {
return stateBase;
}
public Class<T> getBaseClass() {
return stateBaseClass;
}
}
Then in main
:
State state = new State();
StateInstanceDescription<State> stateInstDesc = new StateInstanceDescription<>(state, State.class);
state = stateInstDesc.getBaseClass().newInstance();
Upvotes: 3