2

如何创建一个泛型类,该类从创建/注入此泛型类时放置的泛型类型参数中获取类类型?我的目标是指定 eg MyGeneric<User>,然后泛型类应该能够User在所有方法调用中使用该类。无需User.class另外在泛型的构造函数中显式提供。

就像是:

class MyGeneric<T> {
    public MyGeneric() {
        someService.create(Class<T>, someString);
    }
}

class Usage {
    @Inject
    MyGeneric<User> myuser;
}

这是如何正确完成的?

4

3 回答 3

2

由于运行时类型擦除,没有办法做到这一点。

通常的方法是(正如您所暗示的)将一个实例(Class<T>称为类型令牌)传递给构造函数。鉴于您的代码模式,您会坚持使用这种方法。

于 2012-10-29T11:23:57.247 回答
0

这有点棘手,但使用来自 Guice 的 TypeLiteral,您可以执行以下操作:

public class ReiHashMap<K,V> extends HashMap<K,V> {

   private final TypeLiteral<K> keyTL;

   public ReiHashMap(TypeLit<K> keyTL ) {
       this.keyTL = keyTL;
   }

   @Override
   public V get(Object o) {
       if ( !keyTL.getRawType().isAssignableFrom( o.getClass() )) {
           throw new IllegalArgumentException( "object " + o + " (class "+ o.getClass() +")ist not of type " + keyTL);
       }
       return super.get(o);
   }
   ...

这是 HashMaps 的扩展,可以在运行时检查 get 参数的类型。

于 2012-10-29T11:29:36.193 回答
0

您可以做的是在超类中编写实例化代码,然后为每个特定的泛型类型扩展它(子类中需要很少或不需要代码,但子类是强制性的,因为它们是避免类型擦除的唯一方法):

abstract class MyGeneric<T> {

    private T instance;

    public MyGeneric(String str) {
        // grab the actual class represented by 'T'
        // this only works for subclasses of MyGeneric<T>, not for MyGeneric itself !
        Class<T> genericType = (Class<T>) ((ParameterizedType)getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
        try {
            // instantiate that class with the provided parameter
            instance = genericType.getConstructor(String.class).newInstance(str);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
}

class MyUser extends MyGeneric<User> {
    public MyUser() {
        // provide the string to use for instantiating users...
        super("userStr");
    }
}

class User { /*...*/ }

编辑:制作泛型类abstract以强制使用子类。

它也可以与匿名类一起使用,例如:

new MyGeneric<User>("..string...") {}

我认为这是您可以获得的最接近您最初目标的方式...

于 2012-10-29T11:38:54.097 回答