public abstract class AbstractWorker {
public abstract void execute();
}
public class Config {
public final String name;
public Config(final String name) {
this.name = name;
}
}
public abstract class AbstractWorkerFactory<C extends Config> {
public abstract AbstractWorker createWorker(final C configuration);
}
public class Service {
public AbstractWorker caramba(final AbstractWorkerFactory<? extends Config> factory, final Config configuration) {
// it is not compile :(
return factory.createWorker(configuration);
}
}
以下代码正常工作
public <C extends Config> AbstractWorker caramba(final AbstractWorkerFactory<C> factory, final C configuration) {
return factory.createWorker(configuration);
}
但是使用Service的代码无法指定泛型类型。是否可能有其他解决方案。
更新(经过meriton回答):
1. Concentrate Factory和Configuration实例在不同的地方(类)创建。
2.
public static class MegoConfig extends Config {
public static class WorkerFactory extends AbstractWorkerFactory<Config> {
public static class MegoWorkerFactory extends AbstractWorkerFactory<MegoConfig> {
MegoWorkerFactory支持MegoConfig和Config。
我的任务的新解决方案。
public AbstractWorker caramba(final AbstractWorkerFactory<? super MegoConfig> factory, MegoConfig configuration) {
return factory.createWorker(configuration);
}
new Service().caramba(new WorkerFactory(), new MegoConfig(""));
new Service().caramba(new MegoWorkerFactory(), new MegoConfig(""));
非常感谢大家的回答!
答案 0 :(得分:3)
声明
public AbstractWorker caramba(final AbstractWorkerFactory<? extends Config> factory, final Config configuration) {
过于宽泛;它接受任何具有任何配置的WorkerFactory,而不表示每个workerfactory都需要特定的配置。也就是说,写
是完全合法的caramba(new AbstractWorkerFactory<FooConfiguration>() { ... }, new BarConfig());
即使WorkerFactory无法使用该配置。
另一方面,宣言
public <C extends Config> AbstractWorker caramba(final AbstractWorkerFactory<C> factory, final C configuration)
通过两个参数声明中出现的相同类型变量,正确表示提供的WorkerFactory必须与提供的配置兼容。
但是使用Service的代码无法指定泛型类型。是否可能有其他解决方案?
我不明白;为什么不能呢?你为什么需要另一个解决方案?
答案 1 :(得分:0)
这些都在同一个文件中吗?您不能在单个源文件中拥有多个公共类。但这并不能解释泛型错误。
我把它们放在你的Service
类的源文件中,并且编译得很好:
class Config {}
class AbstractWorker {}
abstract class AbstractWorkerFactory<C extends Config> {
public abstract AbstractWorker createWorker(final C configuration);
}
使用Service
的代码是什么?
答案 2 :(得分:0)
不,您提供的解决方案可能是最好的:
public <C extends Config> AbstractWorker caramba(final AbstractWorkerFactory<C> factory, final C configuration) {
return factory.createWorker(configuration);
}
或者,您可以在caramba方法中使用原始签名,而不使用通配符,但这会带来其他问题,例如编译器警告。