你好可以投一个名单吗?
我有一个抽象类,它有一个方法,它采用某种List <>,在for循环中迭代它,获取该列表中的每个对象,并调用子类实现的insertItem抽象方法,基本上拉出正确的项目中的数据,然后最终将它们插入数据库表.
这是超类方法:
protected void insertAllItemsToDb(List<Object> items, String table) {
// open db and table
database().beginTransaction();
// clear all data from table
clearTable(table);
// call a insert statement to insert each column from an item
for (Object object : items) {
insertItem(object, table);
}
// close db
database().endTransaction();
database().close();
}
Run Code Online (Sandbox Code Playgroud)
在子类中,这是一个覆盖方法:我能够在这里强制转换对象.
@Override
protected void insertItem(Object object, String table) {
CalendarEventItem item = (CalendarEventItem) object;
eventItemValue = new ContentValues();
eventItemValue.put(LABEL_EVENTS_TITLE, item.getEventTitle());
eventItemValue.put(LABEL_EVENTS_LOCATION, item.getEventLocation());
eventItemValue.put(LABEL_EVENTS_DATE, item.getEventStartTime()
.getDate());
eventItemValue.put(LABEL_EVENTS_TIME, item.getEventStartTime()
.getTime());
eventItemValue.put(LABEL_EVENTS_TIMEZONE, item.getEventStartTime()
.getTimeZone());
database.insert(TABLE_NAME_EVENTS, null, eventItemValue);
}
Run Code Online (Sandbox Code Playgroud)
然后我使用以下方法从超类中调用该方法:
events = (List<CalendarEventItem>) items;
insertAllItemsToDb(events, TABLE_NAME_EVENTS);
Run Code Online (Sandbox Code Playgroud)
但我收到一个编译错误,说你不能施展它.关于如何实现这一点的任何想法,而不必复制您在insertAllItemsToDb()中看到的相同步骤和代码
将一个通用参数添加到抽象类:
public abstract class BaseClass<T>{
protected abstract void insertItem(T object, String table);
protected void insertAllItemsToDb(List<T> items, String table) {
//...
for (T object : items) {
insertItem(object, table);
}
//...
}
}
Run Code Online (Sandbox Code Playgroud)
现在你不需要任何转换,子类只需要使用正确的类型:
public class FooBar extends BaseClass<Phleem>{
protected void insertItem(Phleem object, String table){
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
一个List<Object>是不是一个List<CalendarEventItem>,所以编译器是正确的,他们不是浇注料.快速的原因,这是一个例子:
final List<Object> listOne = new ArrayList<Object>();
listOne.add("Hello World");
final List<CalendarEventItem> listTwo = new ArrayList<CalendarEventItem>();
listTwo.addAll(listOne); // Correctly disallowed by compiler
// This is what you're trying to do
List<CalendarEventItem> sneakyList = (List<CalendarEventItem>)listOne;
listTwo.addAll(sneakyList);
Run Code Online (Sandbox Code Playgroud)
因此,不允许在两种不兼容的类型之间进行铸造,因为它会破坏类型安全保证.
你几乎肯定想要声明你的insertAllItemsToDb方法来取一个List<?>而不是一个List<Object>,因为你不关心元素类型是什么,只要它是Object的子类(这是非常真实的).
这应该可以防止您在不可转换的类型之间进行转换,并且通常可以更好地使用.
有关更多信息,请查看Angelika Langer出色的Java Generics常见问题解答中的Wildcard Bounds部分.事实上,如果你还没有,你应该看看整个事情.要带走的一般原则是,在大多数情况下,您应该在用于方法参数的集合上使用通配符 - 如果您同时读取和写入集合(这实际上非常罕见),那么您唯一不会这样做.
| 归档时间: |
|
| 查看次数: |
4010 次 |
| 最近记录: |