Java – generics using arrayadapters
I encountered a problem trying to create a generic arrayadapter This may be related to my limited understanding of generics in Java, and I hope someone can let me be straightforward Basically, I have an abstract basic adapter class:
public abstract class BaseAdapter<T> extends ArrayAdapter<T>
{
....
private List<T> items;
....
protected abstract List<T> build(JSONArray jsonArray);
....
@Override
public T getItem(int position)
{
return items.get(position);
}
....
}
Then I have an adapter that extends this base class:
public class MyAdapter extends BaseAdapter<BaseModel>
{
....
@Override
protected List<BaseModel> build(JSONArray jsonArray)
{
if (useBaseModel())
{
return BaseModel.buildBaseModels(jsonArray); //returns List<BaseModel>
}
else
{
return SubclassModel.buildSubclassModels(jsonArray); //returns List<SubclassModel>
}
}
....
}
The model is defined as:
public class BaseModel{...}
public class SubclassModel extends BaseModel{....}
This does not compile because even if subclassmodel extends basemodel, their list is different This post (most effective way to cast list < subclass > to list < baseClass >) explains this and says to use it instead:
List<? extends BaseModel>
When I change to:
public class MyAdapter extends BaseAdapter<? extends BaseModel>
{
...
protected List<? extends BaseModel> build(JSONArray jsonArray)
...
}
The error on the build method disappeared, but now there is a class level error description: getitem (int) and Android. Net in baseadapter widget. Getitem (int) conflict in arrayadapter; An incompatible return type was attempted
It seems that getitem should return a type? Extend basemodel, who is it – can anyone provide advice?
thank you!
Solution
Well, my java SDK doesn't even let me compile
public class MyAdapter extends BaseAdapter<? extends BaseModel>
It expects an extended unbounded class or interface But it doesn't matter. If this is an option, the solution to the problem is to change the baseadapter class:
public abstract class BaseAdapter<T> extends ArrayAdapter<T>
{
....
private List<T> items;
....
protected abstract List<? extends T> build(JSONArray jsonArray);
....
@Override
public T getItem(int position)
{
return items.get(position);
}
}
then
public class MyAdapter extends BaseAdapter<BaseModel>
{
...
protected List<? extends BaseModel> build(JSONArray jsonArray)
...
}
Work with previous code
Edit:
Forget to explain why your first solution doesn't work:
Language spec says
This means that although subclassmodel extends basemodel, it does not mean that list extends list
