2016-05-13 19 views
-2

私は少し遅くなるかもしれないので、私はそれが簡単な質問だったと思ったものを解決するために把握することはできません。Javaジェネリックとリフレクション|どのようにジェネリッククラスをインスタンス化する

私は基本的にこのような状況があります。

1)基底クラスMyDAO

public abstract class MyDAO<K, E> implements DAO<K, E> 
{ 
    .... 
} 

2)指定されたパッケージにMyDAO具象クラスの実装の束は、言う:

public class TaxonomyDAO extends MyDAO<Integer,Taxonomy>{ 

    .... 
} 

すべてのクラスrelevantoを特徴MyDAOは、基本的に特定のDAOを追加延びます彼らのE要素に。私は、このクラスが存在する場合、WhateverClassDAOのインスタンスを提供するためにリフレクションを使用し、そうでない場合はベースMyDAOを返すことを目標とする汎用ファクトリを作成しています。 Kが常に整数であるとしましょう。

私はこのような何か書いている:

public Object getDAOForEntity(Class c) 
    { 
     createEmfa(); 

     try { 
      Class eDao = Class.forName(getClass().getPackage().getName()+c.getSimpleName()+"DAO"); 
      Constructor<?> cons = eDao.getConstructor(EntityManagerFactory.class);    
      return cons.newInstance(emfa); 
     } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); 
      return new MyDAO<Integer,?????>(emfa) {}; 

     }   
    } 

このクラス、Class c(たとえばWhateverClass)指定されたパラメータ化コンストラクタを使用してWhateverClassDAOのインスタンスを作成するために反射を使用しようとします。 ***DAOクラスは工場の同じパッケージにあると見なされます(私はここで投稿するのに十分シンプルです)。

反射で失敗したのでWhateverClassDAOがないと仮定してMyDAO<Integer,WhateverClass>を返したいと思いますが、そこには正しいE引数を渡すことができません。私は運のない引数としてClass<E>を渡そうとしました。私は基本的に何に代わるべきか疑問に思っています。

これは範囲外ですが、このコードはすべてシングルトンEJBの内部にあります。

適切なドキュメントへのリンクの形であっても、どんな助けも大歓迎です。

+0

Chuck Norrisだけがjavaで抽象クラスをインスタンス化できます。 – aviad

+0

良い、私はそれに値する – elbuild

+0

私は怒っていないことを願っています。ちょうど冗談;)そのようなDAOが存在しない場合、私はちょうどオプションの不在を返したでしょう。 – aviad

答えて

1

クラスClassも一般的なものであり、あなたはそれから正しい一般的なパラメータを推測することができます

public <E> Object getDAOForEntity(Class<E> c) { 
    try { 
     // ... 
    } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
     return new MyDAO<Integer,E>(emfa) {}; 
    } 
} 
+0

私はこれまでに型宣言を忘れました< E >メソッド宣言の開始... 7.20 PMここ。休憩時間。あなたの素早い答えをありがとう:) – elbuild

+0

私は2分で受け入れるよ – elbuild

1

あなたは一般的な方法を作成し、また、より良い、それはあなたの代わりに、オブジェクトの基本クラスをDAO返し行う必要があります

public <E> MyDAO<Integer, E> getDAOForEntity(Class<E> c) { 
    ... 
    try { 
     Class<MyDAO<Integer, E>> eDao = (Class<MyDAO<Integer, E>>)(Class<?>)Class.forName(getClass().getPackage().getName()+c.getSimpleName()+"DAO"); 
     Constructor<MyDAO<Integer, E>> cons = eDao.getConstructor(EntityManagerFactory.class);    
     return cons.newInstance(emfa); 
    } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
     return new MyDAO<Integer,E>(emfa) {}; 
    }   
    } 
+0

私はそれを返しています。私はすぐに投稿する前にコードを編集しました。また、クラス名は – elbuild

+0

ではありません。キャスト時の警告を取り除くために、@SuppressWarnings( "unchecked")を追加することもできます – yurgis

関連する問題