0

私は次のようにいくつかの一般的なものを書いてDAOいます

public class MyGenericDAO<T> {

      Class<T> clazz;

      public void doSome(){
        for(int =0 ;i<14;i++){
            //do something
           }
      }
}

今、T のタイプに基づいて clazz を初期化したいですか? .どうすればいいですか?

たとえば、誰かがそうする場合MyGenericDAO<Xyz> = new MyGenericDAO<MyGenericDAO>() 、タイプは であるT 必要がありますXyz

どうすればいいですか?反省なしで可能ですか?

4

3 に答える 3

4

残念ながら、リフレクションでは不可能です。必要な場合は、引数MyGenericDaoを取るコンストラクターを作成する必要があります。Class<T>

public MyGenericDao(class<T> clazz) {
  this.clazz = clazz;
}
于 2013-03-04T21:39:16.717 に答える
3

残念ながら、型の消去により、 の型clazzに初期化する唯一の方法Tは、コンストラクターで対応するクラスを渡すことです。

MyGenericDAO(Class<T> clazz) {
    this.clazz = clazz;
}

java.lang.Classが汎用化された理由の 1 つは、まさにこのパターンをサポートするためです。TinはinにClass<T>対応している必要があるため、コンパイラは型チェックを行うことができます。TMyGenericDAO<T>

于 2013-03-04T21:39:12.280 に答える
0

型引数は実行時に渡されないため、呼び出し元のコードはトークンClass<T>を渡して実行時にオブジェクトを構築する必要があります。実行時にオブジェクトを再構築するために渡すことができるさまざまなオブジェクトがあるため、トークンと名付けました。次に例を示します。Class<T>

  • a String、一緒に使用するClass.forName(name)
  • Class<T>オブジェクト_
  • 型 token 、つまり、引数が型変数でもワイルドカード (境界付きかどうかも問わない) でもないパラメータ化された型のnew List<String>(){}サブクラスnew

タイプ トークンの場合:

public class MyGenericDAO<T> {

  @SuppressWarnings("unchecked")
  public Class<T> getTypeParameter() throws Exception {
    Type type = ((ParameterizedType) getClass().getGenericSuperclass())
           .getActualTypeArguments()[0];
    return (Class<T>) type;
  }
}

Typeを にキャストすると、未チェックの変換があることに注意してくださいClass<T>。呼び出しコードは次のようになります。

MyGenericDAO<Foo> dao = new MyGenericDAO<Foo>(){};
// Then if you want an instance
Foo foo = dao.getTypeParameter().newInstance();

ここでも、中括弧に注意してください。スーパー タイプ トークンは、コンパイル時に生成された実際のクラスがある場合にのみ機能するためです。このアプローチは、クライアント コードがコントラクトを尊重し、DAO オブジェクトが必要になるたびに匿名の内部クラスを使用する場合にのみ機能します (それ以外の場合は魔法がgetTypeParameter()消えます) 。

于 2013-03-04T23:19:04.247 に答える