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之所以被通用化,其中一个原因就是为了支持这种模式。由于TinClass<T>必须与 in 相对应TMyGenericDAO<T>编译器将能够为您进行类型检查。

于 2013-03-04T21:39:12.280 回答
0

类型参数不会到达运行时,因此调用代码必须传递一个令牌才能在运行时构造Class<T>对象。我将其命名为令牌,因为您可以传递许多不同的对象来Class<T>在运行时重建对象,例如:

  • a String, 与Class.forName(name)
  • 一个Class<T>对象
  • 类型标记,即参数化类型的子类,其参数既不是类型变量也不是通配符(有界或无界),例如 a 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;
  }
}

请注意,当您将 转换TypeClass<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 回答