Java Generics通配符扩展了问题

时间:2010-12-07 21:00:06

标签: java generics

你能帮帮我吗?以下代码示例:

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(""));

非常感谢大家的回答!

3 个答案:

答案 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方法中使用原始签名,而不使用通配符,但这会带来其他问题,例如编译器警告。