我正在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();
它应该可以正常工作吗?
答案 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
没有以任何方式连接,因此类型检查员正确拒绝该程序。 (例如,如果?_1
为Integer
且?_2
为String
,该怎么办?)
我的版本修复了这个问题,只需告诉编译器,虽然我们不知道我们在说什么类型,但要知道它是相同的未知类型到处。这让typechecker知道构造函数生成的任何类型都与列表接受的类型相同。