使用与子类构造函数不同的参数调用基础构造函数

时间:2013-03-11 15:16:43

标签: java generics constructor

我确定这是重复的,但我搜索的关键字太常见了......我得到很多点击量,因为我不想要的东西。我来自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>实例化抽象类。

3 个答案:

答案 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();