Having the following classes:
public interface Step<C extends Config> {
void setConfig(C config);
}
and
public class ValidationStep implements Step<ValidationConf> {
public void setConfig(ValidationConf conf) {}
// implementation
}
and
public class ProcessStep implements Step<ProcessConf> {
public void setConfig(ProcessConf conf) {}
// implementation
}
and
public interface Config {
Class<? extends Step> type();
}
and
public class ValidationConf implements Config {
public Class<? extends Step> type() {
return ValidationStep.class;
}
}
and
public class ProcessConf implements Config {
public Class<? extends Step> type() {
return ProcessStep.class;
}
}
so, the application needs to dynamically instantiate Step subclasses objects, set the configuration accordingly and run the step, like this.
List<Config> configs = loadConfigsFromRepository(); // contain all subtypes of Config
for (Config conf: configs) {
Step<? extends Config> step = conf.type().getDeclaredConstructor().newInstance();
step.setConfig(conf); // compiler complains
}
Error message:
"The method setConfig(capture#8-of ? extends Config) in the type
Step<capture#8-of ? extends Config> is not applicable for the
arguments (Config)".
Checking the documentation, looks like Java won′t be friendly in this case:
https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html
What are the possible solutions to overcome this code restriction step.setConfig(conf);
?
EDITED [SOLUTION]
Code can be viewed here: https://github.com/danieldestro/cucumber-salad/tree/generics/src/main/java/my/generics
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…