1

これは重複していると思いますが、検索のキーワードが一般的すぎます... 探していないものに対して、多くのヒットがあります。私は 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使用して基本クラスをインスタンス化する、クラスのパラメータなしのコンストラクタを作成するにはどうすればよいでしょうか。私はこれを書くことができるようにしたい:EmployeeUUID

EmployeeRepository foo = new EmployeeRepository();

Class<Employee>...そして、とで抽象クラスをインスタンス化しますClass<UUID>

4

3 に答える 3

6

AFAIK、デフォルトのサブクラスコンストラクターからスーパークラスコンストラクターを呼び出す以外に、これを回避する方法はありません。

public EmployeeRepository() {
    super(Employee.class, UUID.class);

    ...
}
于 2013-03-11T15:18:40.567 に答える
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;
    }
}

ただし、本当の問題は、なぜ型を持ちたいのかということです。

于 2013-03-11T15:23:25.063 に答える
0

別の方法として、ビルダーパターンを使用します。

public class EmployeeRepository extends BaseRepository<Employee, UUID>{
   public static EmployeeRepository newInstance() {
       return new EmployeeRepository(Employee.class, UUID.class);
   }
   ...
}

EmployeeRepository foo = EmployeeRepository.newInstance();
于 2013-03-11T15:24:45.493 に答える