我正在尝试创建的情况如下:
我有一个包含静态模板方法的基类,该方法接收由数据库中的查询填充的ResultSet
,并返回包含正确结果的列表。
我有一些派生自上面引用的类的类,它们代表数据库中的每个表,并且所有类都有一个接收ResultSet
并构建对象的构造函数。
我写的代码是:
public class TableBase
{
public static <T extends TableBase> List<T> getResults(ResultSet p_Rs) throws SQLException, InstantiationException, IllegalAccessException
{
List<T> v_Table = new ArrayList<T>();
T v_TB = null;
while(p_Rs.next())
v_Table.add(new T(p_Rs));
return v_Table;
}
}
我得到的错误是:Cannot instantiate the type T
。
我很清楚,编译器必须“知道”所有子类都将实现接收ResultSet
变量的构造函数,但我无法创建“抽象构造函数” 。
有没有人知道如何解决这个问题?
提前谢谢大家。
答案 0 :(得分:2)
您无法实例化泛型类型。
您可以使用任何一个工厂
public static <T extends TableBase> List<T> getResults
(ResultSet p_Rs, Factory<T> factory)
//Create instance using factory
或类别类型。
public static <T extends TableBase> List<T> getResults
(ResultSet p_Rs, Class<T> type)
//type.newInstance()
答案 1 :(得分:1)
你做不到。您必须准确地告诉运行时类型。
也许你可以这样做:
TableBase
必须有默认构造函数。 TableBase
必须有setResultSet方法。
public class TableBase {
public static <T extends TableBase> List<T> getResults(ResultSet p_Rs, Class<T> clazz)
throws SQLException, InstantiationException, IllegalAccessException {
List<T> v_Table = new ArrayList<T>();
T v_TB = clazz.newInstance();
while (p_Rs.next())
v_TB.setResultSet(p_Rs);
v_Table.add(v_TB);
return v_Table;
}
}
答案 2 :(得分:0)
您可以使用反射,例如:
while(p_Rs.next())
v_Table.add(newInstance(T, p_Rs));
public <T extends TableBase> T newInstance(T t, ResultSet p_Rs){
try {
Constructor constructor = t.getClass().getDeclaredConstructor(ResultSet.class);
return (T)constructor.newInstance(p_Rs);
} catch (Exception e) {
throw new RuntimeException();
}
}