泛型在运行时不具体化.由于信息不存在,您有两种解决方案:
>它可以通过在类中引入私有字段来在编译时存储
>您可以使用反射在运行时从实例中解析泛型类型.
这里有一个私有字段T和构造函数的示例,从您的代码开始:
public abstract class MyRepository {
private Class type;
public MyRepository(Class type) {
this.type = type;
}
public List getList() {
Cursor cursor = getCursor(null, null); // how to do this?
// excess code removed, rest of function not relevant to question
return null;
}
protected Cursor getCursor(String selection, String[] selectionArgs) {
DatabaseObject databaseObject = instantiateFromType(); // how to do this?
String tableName = databaseObject.getTableName();
String[] projection = databaseObject.getProjection();
String sortOrder = databaseObject.getDefaultOrderColumn() + " " + DEFAULT_SORT_ORDER;
Cursor cursor = database.query(
tableName,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
return cursor;
}
private DatabaseObject instantiateFromType() {
try {
T interfaceType = (T) type.newInstance();
return interfaceType;
}
catch (Exception e) {
// TODO to handle
}
}
}
在这里你的DogRepository:
public class DogRepository extends MyRepository {
public DogRepository() {
super(Dog.class);
}
}
使用实现DatabaseObject的Dog:
public class Dog implements DatabaseObject{
//todo
}
回答你的评论.
The line DogRepository(Class type), is it necessary to pass in
the class as an argument?
不是不需要(对不起,我读错了你的评论)).
更进一步,正如您可能注意到的那样,混凝土储存库的构造函数是锅炉板代码.
如果使用反射来解析DogRepository中使用的泛型后面的类,则不需要再为其定义自定义构造函数.
例如,要检索存储库中使用的类型,Spring使用JDK反射机制使用自己的库完成工作,具体如下:
Map source = GenericTypeResolver.getTypeVariableMap(DogRepository.class);
Spring有它的库,因为它使用了很多反射.
但在您的情况下,您也可以在不使用lib但使用自己的实用程序类的情况下完成工作.这是一个从存储库实例中解析泛型类型的示例.
DogRepository dogRepository = new DogRepository();
Class> typeClass = (Class>) ((ParameterizedType) dogRepository.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
System.out.println("typeClass=" + typeClass );
使用反射来解析MyRepository构造函数中的有效泛型类型:
public abstract class MyRepository {
private Class type;
public MyRepository() {
type = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
...
}
存储库具体类不再需要自定义构造函数:
public class DogRepository extends MyRepository {
}