将 Cursor 转换为通用对象 android
Converting Cursor into generic object android
我正在为 Android 在 SQLite 上实现一些功能,因此我可以将它们用于通用对象。
我在使用 "SelectAll" 方法时遇到了一些问题。我可以将我的对象查询到游标中,只有它的 class。
我正在这样做:
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:
因为这个方法是在每个使用这些方法的 class 实现的 "generic class" 中,所以创建它怎么样
public class<T> foo{
public <T> ArrayList<T> SelectAll(){
//no more need class, but work with "this" world
...
}
}
并使用它而不是每次都调用 class?可能吗?
我会这样称呼它
ArrayList<Foo> foo = new Foo().SelectAll();
应该没问题吧?
使用通用类型参数而不是通配符将解决问题:
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
怎么办?)
我的版本解决了这个问题,只是告诉编译器虽然我们不知道我们在谈论什么类型,但要知道到处都是相同未知类型。这让类型检查器知道构造函数产生的任何类型与列表接受的类型相同。
我正在为 Android 在 SQLite 上实现一些功能,因此我可以将它们用于通用对象。 我在使用 "SelectAll" 方法时遇到了一些问题。我可以将我的对象查询到游标中,只有它的 class。 我正在这样做:
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:
因为这个方法是在每个使用这些方法的 class 实现的 "generic class" 中,所以创建它怎么样
public class<T> foo{
public <T> ArrayList<T> SelectAll(){
//no more need class, but work with "this" world
...
}
}
并使用它而不是每次都调用 class?可能吗? 我会这样称呼它
ArrayList<Foo> foo = new Foo().SelectAll();
应该没问题吧?
使用通用类型参数而不是通配符将解决问题:
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
怎么办?)
我的版本解决了这个问题,只是告诉编译器虽然我们不知道我们在谈论什么类型,但要知道到处都是相同未知类型。这让类型检查器知道构造函数产生的任何类型与列表接受的类型相同。