mercredi 16 septembre 2020

How to use method with generics and inheritance?

Having the following classes:

public interface Step<C extends Config> {
  void setConfig(C config);
  void run(Context ctx);
}

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 dinamically 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

  step.run(context);
}

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);?





Aucun commentaire:

Enregistrer un commentaire