如何创建泛型类,它从创建/注入此泛型类时放置的泛型类型参数中获取类类型?
我的目标是指定例如MyGeneric<User>
,然后泛型类应该能够在所有方法调用中使用User
类。无需在通用的构造函数中明确提供User.class
。
类似的东西:
class MyGeneric<T> {
public MyGeneric() {
someService.create(Class<T>, someString);
}
}
class Usage {
@Inject
MyGeneric<User> myuser;
}
这是如何完成的?
答案 0 :(得分:2)
由于运行时type erasure,无法执行此操作。
通常的方法是(正如您所提到的)将Class<T>
的实例 - 称为type token - 传递给构造函数。鉴于您的代码模式,您仍然坚持这种方法。
答案 1 :(得分: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参数的类型。
答案 2 :(得分: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...") {}
我认为这是你最接近你最初的目标......