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.