I'm creating my own MVP framework, and I'm running into trouble with the generics.
My presenter is defined like this, with an inner class holding references to child elements which are also generic presenters:
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);
}
}
}
and I have a concrete implementations of this
public class ResultsPresenter extends Presenter<ResultsView, Results>
and
public class SearchPresenter extends Presenter<SearchView, StringKey>
{
// ...
public void bind()
{
addStage(ResultsPresenter.class, "results");
}
}
where ResultsView, SearchView extend View and Results, StringKey implement Key
The method addStage(...) throws the following compile-time error:
**The method addStage(Class<Presenter<TChildView,TChildKey>>, String) in the type
Presenter<SearchView,StringKey> is not applicable for the arguments
(Class<ResultsPresenter>, String)**
Any help, or better practices, would be greatly appreciated
Try to change the method prototype to:
public <TChildView extends View, TChildKey extends Key> void addStage(Class<? extends Presenter<TChildView, TChildKey>> stage, String name)
pay attention that I changed Class<Presenter<TChildView, TChildKey>>
to Class<? extends Presenter<TChildView, TChildKey>>
. This will allow you to pass Class of Presenter's subclass instead of Presenter itself.
I've not tried it myself, but out of a hunch I'd say that
addStage(Class<Presenter<TChildView, TChildKey>> stage, String name)
should be
addStage(Class<Presenter<? extends TChildView,? extends TChildKey>> stage, String name)
Try Alex suggestion first. Keeps the code more readable and makes somewhat more sense than mine. If both fail, combine them.
精彩评论