我确定这是重复的,但我搜索的关键字太常见了......我得到很多点击量,因为我不想要的东西。我来自C#,Java泛型似乎有点落后于.NET实现,所以这对我来说非常令人沮丧。
我有一个抽象类BaseRepository,如下所示:
public abstract class BaseRepository<T, K> implements Repository<T, K> {
private Class<T> type;
private Class<K> keyType;
public BaseRepository(Class<T> clazz, Class<K> kClazz) {
type = clazz;
keyType = kClazz;
}
protected Class<T> getType() {
return type;
}
protected Class<K> getKeyType(){
return keyType;
}
}
现在我想从我的基类派生EmployeeRepository
,如此:
public class EmployeeRepository extends BaseRepository<Employee, UUID>{
}
使用c#,我不需要做出如此英勇的努力来实例化基类,但似乎java的泛型实现要求你在构造函数中传递泛型类型。
那么如何为我的EmployeeRepository
类创建一个无参数构造函数,该类实例化实体类型为Employee
且密钥类型为UUID
的基类?我希望能够写下这个:
EmployeeRepository foo = new EmployeeRepository();
...并使用Class<Employee>
和Class<UUID>
实例化抽象类。
答案 0 :(得分:6)
AFAIK,除了从默认子类构造函数中调用超类构造函数之外,没有办法解决这个问题:
public EmployeeRepository() {
super(Employee.class, UUID.class);
...
}
答案 1 :(得分:1)
您可以使用反射来确定通用参数的类型。
public abstract class BaseRepository<T, K> implements Repository<T, K> {
private Class<T> type;
private Class<K> keyType;
public BaseRepository() {
Type[] actualTypes = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments();
this.type = (Class<T>)actualTypes[0];
this.keyType = (Class<K>)actualTypes[1];
}
protected Class<T> getType() {
return type;
}
protected Class<K> getKeyType(){
return keyType;
}
}
然而,真正的问题是:你为什么要拥有这些类型?
答案 2 :(得分:0)
作为替代方案,请使用Builder模式:
public class EmployeeRepository extends BaseRepository<Employee, UUID>{
public static EmployeeRepository newInstance() {
return new EmployeeRepository(Employee.class, UUID.class);
}
...
}
EmployeeRepository foo = EmployeeRepository.newInstance();