具有以下类别:
public interface Step<C extends Config> {
void setConfig(C config);
}
和
public class ValidationStep implements Step<ValidationConf> {
public void setConfig(ValidationConf conf) {}
// implementation
}
和
public class ProcessStep implements Step<ProcessConf> {
public void setConfig(ProcessConf conf) {}
// implementation
}
和
public interface Config {
Class<? extends Step> type();
}
和
public class ValidationConf implements Config {
public Class<? extends Step> type() {
return ValidationStep.class;
}
}
和
public class ProcessConf implements Config {
public Class<? extends Step> type() {
return ProcessStep.class;
}
}
因此,应用程序需要动态实例化步骤子类对象,相应地设置配置并运行步骤,如下所示。
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
}
错误消息:
"方法setConfig(捕获#8-of?扩展Config)在类型Step中
查看文档,在这种情况下,Java看起来不友好:https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html
克服此代码限制的可能解决方案是什么。setConfig(conf) ?
编辑[解决方案]
可在此处查看代码:https://github.com/danieldestro/cucumber-salad/tree/generics/src/main/java/my/generics
你的方法不完全正确。我建议您在真正需要反射之前不要使用反射。
注意,所有这些实现都应该隐藏在包中,只有Step
接口应该是public
。Config
实现保存所有数据以创建Step
类,所以只需将其委托给它。
package steps
public interface Step<C extends Config> {
void run(Context context);
}
private final class ValidationStep implements Step<ValidationConf> {
private final ValidationConf config;
public ValidationStep(ValidationConf config) {
this.config = config;
}
}
private class ProcessStep implements Step<ProcessConf> {
private final ProcessConf config;
public ValidationStep(ProcessConf config) {
this.config = config;
}
}
public interface Config {
Step<? extends Config> createStep();
}
private class ValidationConf implements Config {
public Step<ValidationConf> createStep() {
return new ValidationStep(this);
}
}
private class ProcessConf implements Config {
public Step<ValidationConf> createStep() {
return new ProcessConf(this);
}
}
package foo
List<Config> configs = loadConfigsFromRepository();
for (Config config : loadConfigsFromRepository()) {
config.createStep().run(context);
}
去掉通配符。你不需要它。
Step<Config> step = (Step<Config>) conf.type().getDeclaredConstructor().newInstance();
因为<代码>步骤。setConfig(Config)是一个“消费者”,解决“code>不适用于参数(Config)的一种方法是“您得到的错误是使用我在这里演示的下限…”…
…
List< ? extends Config > configs = loadConfigsFromRepository( ); // contain all subtypes of Config
for ( Config conf: configs ) {
Step< ? super Config > step = conf.type( ).getDeclaredConstructor( ).newInstance( );
step.setConfig( conf ); // *set* makes Step a „consumer“
}
…
这样你就不需要另一个答案提出的演员阵容。
我的loadConfigsFromRepository()实现如下…
static List< ? extends Config > loadConfigsFromRepository(){
return of( new ValidationConf( ), new ProcessConf( ) );
}
问题内容: 我有三节课: 现在在我的主要职能中,我做这样的事情: 但这会产生2个编译时错误: 无法将A转换为fileHandler 无法将B转换为fileHandler 如果基类不是泛型的,那么我如何摆脱这些错误呢? 更新: 我的班级层次结构是: 调用函数的C类或 调用函数的D类。 C和D都从抽象类E派生。 现在,我应该如何在C和D以及E中定义这些功能: 我给出了以下内容: E: C: D: C,
为了在 .NET Core 中使用依赖关系注入,我们构建了一堆存储库接口,供控制器用于数据库交互。 我们有一个< code>EntityBase类,其中包含一些方法,我们的通用存储库接口使用这个基类,例如:< code>IRepository 我想添加一个更具体的 类,该类扩展了 ,以表示我们有一些要按标记筛选的实体。我希望 有一个抽象属性,我可以在控制器中使用该属性,以便我可以抽象出来并重用过滤
我有一个典型的问题,什么是更好的,我认为答案总是视情况而定,但我还是想澄清一下。所以有两种方法: 逻辑是: 我知道由于类型擦除,方法签名存在冲突,所以我的问题不是“为什么我不能同时拥有这两个方法?”,而是“你会选择哪种方法?”。
和这个问题相关的课程: 现在,这似乎已被编译器接受。不幸的是,我不知道/理解如何创建的新实例,。 当然,这确实不起作用:
问题内容: 我正在编写一个流畅的API,以配置和实例化一系列“消息”对象。我有消息类型的层次结构。 为了在使用Fluent API时能够访问子类的方法,我使用了泛型来对子类进行参数化,并使所有的fluent方法(以“ with”开头)都返回泛型类型。注意,我省略了流利方法的大部分内容。其中进行了许多配置。 具体的子类类似地重新定义泛型。 该代码有效,即,我可以实例化任何类并使用所有流利的方法: 以
我有一个典型的问题,什么是更好的,我认为答案总是视情况而定,但我还是想澄清一下。所以有两种方法: 逻辑是: 我知道由于类型擦除,方法签名存在冲突,所以我的问题不是“为什么我不能同时拥有这两个方法?”,而是“你会选择哪种方法?”。