0

所以,我正在尝试为 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 ""; }
}

抱歉,如果这令人困惑,我正在学习来自 PHP 的 Java,所以我可能会以错误的方式解决这个问题,我只是不习惯严格的类型转换

4

1 回答 1

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();
    }
}

然后将 What.class 传递给 Table 构造函数(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 子类。

希望有帮助。

于 2013-08-06T00:40:21.400 回答