2011-12-28 6 views
3

マイGenericDaoがあり得る(K番号)を処理するには:今Javaのジェネリック問題、どのようにTが

public T get(K id); 

私GenericDaoImplがあります:

public T get(K id) { 
    return super.getHibernateTemplate().get(???, id); 
    } 
私が試した:

get(T.class, id); 

コンパイルエラーが発生する:

cannot select from a type variable 

これをどうにかして正しく行うことはできますか?

答えて

3

タイプ消去のため、これはできません。
Classインスタンスをパラメータとして使用する必要があります。

+0

ので:Tは右(クラスタイプ、K ID)を取得しますか? SomeEntityDaoImplがGenericDaoを実装すると、getコールは「悪い」と表示されます。これを解決するには、を取得しますか? – Blankman

+0

@Blankmanコンパイラは 'type'引数から型パラメータを推論するので、呼び出し側は明示的にそれを提供する必要はありません。 – Taymon

1

パラメータ化された具体的なエンティティタイプを把握できるようにGenericDaoを構築する必要があります。例えば、SomeEntityDaoImplは、そのエンティティタイプがSomeEntity.classであることを知ることができるはずです。

いずれ

  1. 自動的にルックアップ反射法を使用GenericDaoに、抽象メソッド、getEntityClassを追加し、適切なエンティティ・クラスを提供するために、各DaoImplでそのメソッドをオーバーライド、または

  2. typeパラメータ(私はParameterizedType.getActualTypeArguments()続いGoogleのGuiceの、からMoreTypes.getGenericSupertype()を使用しました。)

その後、DaoImplはgetEntityClass()を単独で呼び出すことができるので、get()にClassリテラルを渡す必要はありません。

0

GenericDaoImplは抽象的であり、すべての実際の実装はTKバインドされている場合は、あなたリフレクションを使用して型パラメータの値を取得できます。

abstract class GenericDaoImpl<K, T> { 

    public T get(K id) { 
    Class<?> valueClazz = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    return super.getHibernateTemplate().get(valueClazz, id); 
    } 

} 

class StringDao extends GenericDaoImpl<Integer, String> { 
} 

私はideoneでわずかに変更された例を作成し、型クラス、この場合はStringを出力するだけです。

これは、StringDao(および他のすべてのDAO)がGenericDaoImplの直接サブクラスである場合にのみ機能するため、少し脆いです。そして、私が言ったように、GenericDaoImplが抽象ではなく直接使用されることを意図しているなら、それはうまくいかないでしょう。その場合、あなたがしていることが正しいアプローチであるかどうかを検討するべきだと思います。私の経験では、そのように一般的なDAOはうまく動作しません。

1

私の実装:

public abstract class DAOImpl <T, PK extends Serializable> implements DAO<T, PK> { 


    protected abstract Class<T> getEntityClass(); 

    public T findById(PK id){ 
    return (T)getHibernateTemplate().get(getEntityClass(),id); 
    } 

    protected DetachedCriteria createDetachedCriteria(){ 
    return DetachedCriteria.forClass(getEntityClass()); 
    } 

    @SuppressWarnings("unchecked") 
    public List<T> findAll(){ 
    return getHibernateTemplate().findByCriteria(createDetachedCriteria()); 
    } 

} 
関連する問題