我正在创建自己的MVP框架,并且我在使用泛型时遇到了麻烦。
我的演示者是这样定义的,内部类包含对子元素的引用,子元素也是通用的演示者:
public abstract class Presenter<TView extends View, TKey extends Key>
{
protected final HashMap<String, StageInstances<?, ?>> _stages;
public <TChildView extends View, TChildKey extends Key> void addStage(Class<Presenter<TChildView, TChildKey>> stage, String name)
{
_stages.put(name, new StageInstances<TChildView, TChildKey>(stage));
}
// ...
protected class StageInstances<TChildView extends View, TChildKey extends Key>
{
protected Class<Presenter<TChildView, TChildKey>> _presenter;
protected HashMap<Key, Presenter<TChildView, TChildKey>> _instances;
public StageInstances(Class<Presenter<TChildView, TChildKey>> presenter)
{
_presenter = presenter;
_instances = new HashMap<Key, Presenter<TChildView, TChildKey>>();
}
public Presenter<?, ?> getInstance(Key key)
{
if (!_instances.containsKey(key))
{
try
{
_instances.put(key, _presenter.newInstance());
} catch (Exception e)
{
e.printStackTrace();
return null;
}
}
return _instances.get(key);
}
}
}
我有一个具体的实现
public class ResultsPresenter extends Presenter<ResultsView, Results>
和
public class SearchPresenter extends Presenter<SearchView, StringKey>
{
// ...
public void bind()
{
addStage(ResultsPresenter.class, "results");
}
}
其中ResultsView,SearchView扩展View和Results,StringKey实现Key
方法addStage(...)抛出以下编译时错误:
**The method addStage(Class<Presenter<TChildView,TChildKey>>, String) in the type
Presenter<SearchView,StringKey> is not applicable for the arguments
(Class<ResultsPresenter>, String)**
非常感谢任何帮助或更好的实践
答案 0 :(得分:2)
尝试将方法原型更改为:
public <TChildView extends View, TChildKey extends Key> void addStage(Class<? extends Presenter<TChildView, TChildKey>> stage, String name)
请注意我已将Class<Presenter<TChildView, TChildKey>>
更改为Class<? extends Presenter<TChildView, TChildKey>>
。这将允许您传递Class of Presenter的子类而不是Presenter本身。
答案 1 :(得分:1)
我自己没有尝试过,但出于预感,我会说
addStage(Class<Presenter<TChildView, TChildKey>> stage, String name)
应该是
addStage(Class<Presenter<? extends TChildView,? extends TChildKey>> stage, String name)
首先尝试Alex建议。保持代码更易读,并且比我的更有意义。如果两者都失败了,请将它们合并。