我在尝试创建通用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>
它期望扩展后的无界类或接口.但这没关系,如果这是一个选项,问题的解决方案是更改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.