所以,我正在尝试为android sqlite创建一个小型库,我已经掌握了大部分基本功能,但我遇到的问题是将结果作为特定类返回。我有
abstract public class Table<RowClass extends Row>{
public List<RowClass> fetchAll() {
//Fetch the stuff here
//In the while class to add each row to the array
RowClass row = (RowClass) new Row();
}
}
但是每当我尝试记录row.getClass()。getName()时,它总是以Row形式返回,而不是RowClass,它的行为与Row类似,而不是RowClass。如何将它转换为RowClass?
编辑:从表
扩展的内容public class SourcesTable<Rowclass extends Row> extends Table<Row>
{
public String getName()
{ return "sources"; }
public String[] getAllColumns()
{
String[] columns = { "name" };
return columns;
}
}
我用
实例化它Tables sourcesTable = new SourcesTable<SourcesRow>();
List<SourcesRow> list = sourcesTable.fetchAll();
其中
public class SourcesRow extends Row
{
public String toString()
{ return this.data.get("name"); }
}
和
public class Row
{
public String toString()
{ return ""; }
}
很抱歉,如果这令人困惑,我正在学习Java来自PHP,所以我可能会以错误的方式解决这个问题,我只是不习惯严格的类型转换
答案 0 :(得分:2)
这是您的相关代码(您发布的其余代码实际上是不必要的:)):
abstract public class Table<RowClass extends Row>{
public List<RowClass> fetchAll() {
//Fetch the stuff here
//In the while class to add each row to the array
RowClass row = (RowClass) new Row();
}
}
您要问的是如何创建RowClass
的新实例。你不能。 Java不提供有关RowClass类型的信息。由于类型擦除,在运行时不存在有关作为通用参数传递的类型的信息。如果要实例化泛型参数类型的对象,则必须以另一种方式提供该类。例如(为清楚起见,遗漏了异常处理):
abstract public class Table<RowClass extends Row>{
private final Class<RowClass> rowClass; // holds the Class of each row
public Table (Class<RowClass> rowClass) {
this.rowClass = rowClass;
}
public List<RowClass> fetchAll() {
//Fetch the stuff here
//In the while class to add each row to the array
RowClass row = rowClass.newInstance();
}
}
然后将Whatever.class传递给Table构造函数(表是抽象的,因此在您的情况下,您的子类必须将其行的类传递给超级构造函数),例如:
// assume: SpecialRow and MyCustomRow are concrete classes extending Row
// and defined elsewhere.
// scenario 1 - subclass knows row type
public class SpecialTable extends Table<SpecialRow> {
public SpecialTable () {
super(SpecialRow.class);
}
}
// scenario 2 - subclass still lets user specify row type
public class CustomTable <R extends Row> extends Table<R> {
public CustomTable (Class<R> rowClass) {
super(rowClass);
}
}
// usage:
SpecialTable special = new SpecialTable();
CustomTable<MyCustomRow> custom = new CustomTable<MyCustomRow>(MyCustomRow.class);
您也可以将该类传递给fetchAll,例如:
public List<RowClass> fetchAll(Class<RowClass> rowClass) {
//Fetch the stuff here
//In the while class to add each row to the array
RowClass row = rowClass.newInstance();
}
甚至传递一个对象(类似于通用toArray()的工作方式),如:
public List<RowClass> fetchAll(RowClass refObject) {
//Fetch the stuff here
//In the while class to add each row to the array
RowClass row = refObject.getClass().newInstance();
}
了解更多信息:
编辑:如果我猜测你要做的事情是正确的,那么这里有另一种设计方法。
因为Table是抽象的,所以我觉得您正在尝试创建Table子类,其中子类具有自己的特定行类型。在这种情况下,上面的第一个选项(将类类型传递给超级构造函数)将是最合适的。但是,您可能希望考虑让子类实例化自己的已知Row类,并提供允许基类执行此操作的抽象方法,而不是完成所有这些操作,例如:
abstract public class Table { // no generics necessary
// subclasses must override this
abstract protected Row newRow ();
// the base class can use newRow() to let the subclass determine the type
public List<Row> fetchAll () {
// in the while loop to add each row to the array:
Row row = newRow();
}
}
这种方法的主要优点是让知道其特定Row子类的Table子类按其认为合适的方式构造其Row子类。
希望有所帮助。