2011-09-12 5 views
0

私はクラスを持っている:ジェネリックでも可能ですか?

public class GenericDAO<T, ID extends Serializable> { 
private final EntityManager em; 
private final Class<T> entityClass; 
public GenericDAO(EntityManager em) { 
    this.em = em; 
    ParameterizedType genericSuperClass = (ParameterizedType) getClass().getGenericSuperclass(); 
    this.entityClass = (Class<T>) genericSuperClass.getActualTypeArguments()[0]; 
} 
} 

私はこのクラスを拡張した場合、すべてが正常に動作します。今私はこのクラスを直接使用したい(コードを参照してください、CRUDBeanはCRUDServiceの実装です) - 特定のクラスを取得するためにコンストラクタを書き直す必要があります。

@Remote(CRUDService.class) 
@Stateless 
public class CRUDBean<T extends EntityBase> implements CRUDService<T> { 
@PersistenceContext 
private EntityManager entityManager; 

@Override 
public long size(String whereClause, Map<String, Object> whereParameters) { 
    return new GenericDAO<T, Long>(entityManager).size(whereClause, whereParameters); 
} 
} 

どのようにジェネリックサービスを書くか?

+1

が、これはJavaのですか?いずれかの方法で適切なタグを追加してください。ジェネリックは多くの言語で存在します。 – Kobi

+0

はい。それはJavaです。 – Vlada

答えて

1

はい、別のコンストラクタを作成する必要があります。

現在のコンストラクタでは、thisはサブクラスGenericDAOのインスタンスであるとみなされ、そのファクトを使用してgetClass().getGenericSuperclass().getActualTypeArguments()を通してタイプパラメータを取得します。

GenericDAOを直接使用するには、エンティティクラス(実際にはタイプT)を引数として使用するGenericDAOコンストラクタを作成する必要があります。次に、CRUDBean.size()に、またはGenericDAOをインスタンス化する必要がある場所にエンティティクラスを指定します。

あなたはCRUDBeanの実際のクラスを用意していない場合は、3つの選択肢があります。

  1. を引数としてエンティティクラスを取るCRUDBeanコンストラクタを作成します。
  2. エンティティクラスを引数として持つパラメータをsize()に追加します。
  3. 現在のGenericDAOのコンストラクタと同じトリックを使用してください。代わりにgetGenericInterfaces()を使用してください。
+0

どうすれば作成できますか?問題は、CrudService(と実装CrudBean)がEJBサービス(@EJBプライベートCRUDService crudSvc;)です。引数を渡す方法がわかりません: – Vlada

+0

これを考慮に入れた答えが拡張されました – henko

0

クラスを再利用するのではなく、明示的な「型トークン」を使用することをお勧めします。

+0

私は約50の実体を持っています。 50個のインターフェース(CRUDEntity1Service)、50個の型付き実装(CRUDEntity1Bean)、50個の型付けされたDAO(Entity1DAO)を作成したくありません。 – Vlada

0

コンストラクタにクラスのインスタンスを渡すために、この周りに、通常の、そして最も簡単な方法:

public GenericDAO(EntityManager em, Class<T> entityClass) { 
    this.em = em; 
    this.entityClass = entityClass; 
} 

次に、このようにそれを呼び出す:

public long size(String whereClause, Map<String, Object> whereParameters, Class<T> entityClass) { 
    return new GenericDAO<T, Long>(entityManager, entityClass).size(whereClause, whereParameters); 
} 
+0

本当に、 CrudServiceには20個のメソッドがあります(それぞれにentityClassを追加することができます)。もう一度やり直す方法はありますか? – Vlada

+0

コンストラクタでentityClassを渡すラッパーを作成し、内部のGenericDAOオブジェクトのメソッドは、すべての呼び出しにentityClassを追加する - あなたは20回もデリゲートを書く必要がありますが、クライアントクラスはentityClassを一度渡すだけで済みます – Bohemian

関連する問題