我在尝试创建通用 ArrayAdapter 时遇到了问题。这可能与我对 Java 中泛型的理解有限有关,希望有人能帮我弄清楚。基本上我有一个抽象基适配器类:
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);
}
....
}
然后我有一个扩展这个基类的适配器:
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>
}
}
....
}
模型定义为:
public class BaseModel{...}
public class SubclassModel extends BaseModel{....}
这不会编译,因为即使 SubclassModel 扩展了 BaseModel,它们的列表也不等价。这个线程(Most efficient way to cast List<SubClass> to List<BaseClass>)解释了很多,并说要改用这个:
List<? extends BaseModel>
当我更改为:
public class MyAdapter extends BaseAdapter<? extends BaseModel>
{
...
protected List<? extends BaseModel> build(JSONArray jsonArray)
...
}
构建方法上的错误消失了,但现在有一个类级别的错误说明: BaseAdapter 中的 getItem(int) 与 android.widget.ArrayAdapter 中的 getItem(int) 冲突;试图使用不兼容的返回类型。
似乎 getItem 应该返回一个类型?扩展了 BaseModel,它是——有人可以建议吗?
谢谢!
最佳答案
嗯,我的 Java SDK 甚至不让我编译
public class MyAdapter extends BaseAdapter<? extends BaseModel>
在 extends
之后需要一个无界类或接口(interface)。但这没关系,如果可以的话,解决问题的方法是更改 BaseAdapter
类:
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);
}
}
然后
public class MyAdapter extends BaseAdapter<BaseModel>
{
...
protected List<? extends BaseModel> build(JSONArray jsonArray)
...
}
使用前面的代码就可以了。
编辑:
忘记解释为什么您的第一个解决方案不起作用:
Subtyping does not extend through generic types: T <: U does not imply that C <: C.
这意味着虽然 SubclassModel 扩展了 BaseModel,但这并不意味着 List 扩展了 List。
关于java - ArrayAdapter 的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7114109/