2010-12-07 94 views
2

你能幫我嗎?下面的代碼示例:Java泛型通配符擴展問題

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

但是代碼,使用服務無法指定泛型類型。是否有其他解決方案?
UPDATE(經過評估後):
1.集中工廠和配置實例在不同的地方(類)創建。
2.

public static class MegoConfig extends Config { 

public static class WorkerFactory extends AbstractWorkerFactory<Config> { 

public static class MegoWorkerFactory extends AbstractWorkerFactory<MegoConfig> { 

MegoWorkerFactory支持MegoConfig和配置。
我的任務的新解決方案。

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

非常感謝大家的回答!

+2

爲什麼使用Service的代碼不能指定泛型?它有一個AbstractWorkerFactory ,還是Java 1.4? – ILMTitan 2010-12-07 21:17:23

回答

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必須compatiable與所提供的結構,通過出現在這兩個參數聲明相同類型的可變的裝置。

但是使用Service的代碼無法指定泛型類型。是否有其他解決方案?

我不明白;爲什麼不能呢?爲什麼你需要另一種解決方案?

+0

嗨,非常感謝您的回答。我已更新帖子回答你的問題。 – 2010-12-08 06:40:34

0

這些都在同一個文件中嗎?您不能在單個源文件中擁有多個公共類。雖然這不會解決泛型錯誤。

我在源文件與Service類提起這些,並得到了編譯就好了:

class Config {} 
class AbstractWorker {} 
abstract class AbstractWorkerFactory<C extends Config> { 
    public abstract AbstractWorker createWorker(final C configuration); 
} 

那是什麼用Service的代碼?

0

沒有,你所提供的解決方案可能是最好的:

public <C extends Config> AbstractWorker caramba(final AbstractWorkerFactory<C> factory, final C configuration) { 
    return factory.createWorker(configuration); 
} 

另外,您可以使用在的Caramba方法的原始簽名,沒有通配符,但這樣會帶來其他問題,比如編譯器警告。