将Cursor转换为通用对象android

时间:2015-11-06 13:47:04

标签: java android sqlite generics cursor

我正在SQLite for Android上实现一些功能,所以我可以将它们用于通用对象。 我在使用“SelectAll”方法遇到了一些麻烦。我可以将我的对象查询到一个只有它的类的游标。 我这样做:

public ArrayList<?> SelectAll(Class<?> foo){
    Cursor cursor = database.rawQuery("select all from ?", new String[]{foo.getSimpleName()});
    ArrayList<?> list = new ArrayList<>();
    Field[] fields = foo.getFields();
    try {
        Constructor<?> constructor = foo.getConstructor(foo);
        // list.add(constructor.newInstance(  ));
    }catch(Exception ex){
        return list;
    }
    return null;
}

我的问题在于注释行。我有getFields获得的所有参数的数组。但现在我不知道如何循环它们来填充我的对象。 有人可以帮帮我吗?我需要循环光标方式用foo项填充我的ArrayList。

PS:此方法必须是通用的。不具体,所以我必须从我的Field []获取属性而不是直接硬编码。

感谢所有人的建议,我们将不胜感激。

ADD_1:

由于这个方法是在每个使用这些方法的类实现的“泛型类”中,所以如何创建它

public class<T> foo{
    public <T> ArrayList<T> SelectAll(){
        //no more need class, but work with "this" world
    ...
    }
}

使用它而不是每次调用类?可能吗? 我会称之为

ArrayList<Foo> foo = new Foo().SelectAll();

它应该可以正常工作吗?

1 个答案:

答案 0 :(得分:2)

使用泛型类型参数而不是通配符将解决问题:

public <T> ArrayList<T> SelectAll(Class<T> foo){
    Cursor cursor = database.rawQuery("select all from ?", new String[]{foo.getSimpleName()});
    ArrayList<T> list = new ArrayList<>();
    Field[] fields = foo.getFields();
    try {
        Constructor<T> constructor = foo.getConstructor(foo);
        list.add(constructor.newInstance(  ));
    }catch(Exception ex){
        return list;
    }
    return null;
}

原始代码的问题在于Java中的通配符(?)类型是特殊的 - 泛型类型T指的是某些未知类型,尽管如此,它在方法,但?指的是不同的未知类型。

所以你原来的功能说的是:

  • 创建一个包含某些未知类型?_1对象的列表(在程序的第三行)
  • 然后使用?_2类型的构造函数(第6行)实例化对象
  • 尝试将?_2类型的对象放入类型?_1的列表中。

由于?_1?_2没有以任何方式连接,因此类型检查员正确拒绝该程序。 (例如,如果?_1Integer?_2String,该怎么办?)

我的版本修复了这个问题,只需告诉编译器,虽然我们不知道我们在说什么类型,但要知道它是相同的未知类型到处。这让typechecker知道构造函数生成的任何类型都与列表接受的类型相同。