Java 仅通过类型参数创建泛型类?

Java 仅通过类型参数创建泛型类?,java,jakarta-ee,generics,Java,Jakarta Ee,Generics,如何创建泛型类,它从创建/注入此泛型类时放置的泛型类型参数中获取类类型? 我的目标是指定egMyGeneric,然后泛型类应该能够在所有方法调用中使用User类。无需在泛型的构造函数中显式提供User.class 比如: class MyGeneric<T> { public MyGeneric() { someService.create(Class<T>, someString); } } class Usage { @Inj

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

比如:

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

class Usage {
    @Inject
    MyGeneric<User> myuser;
}
类MyGeneric{
公共MyGeneric(){
创建(类,someString);
}
}
类用法{
@注入
myuser;
}

如何正确地执行此操作?

由于运行时间的原因,无法执行此操作


通常的方法是(正如您所提到的)将名为a的
类的实例传递给构造函数。考虑到您的代码模式,您将不得不使用这种方法。

这有点棘手,但使用例如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);
   }
   ...
public类ReiHashMap扩展了HashMap{
私有最终类型文本keyTL;
公共地图(键入keyTL){
this.keyTL=keyTL;
}
@凌驾
公共V get(对象o){
如果(!keyTL.getRawType().isAssignableFrom(o.getClass())){
抛出新的IllegalArgumentException(“对象”+o+“(类”+o.getClass()+)不是“+keyTL”类型);
}
返回super.get(o);
}
...

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

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

抽象类MyGeneric{
私人T实例;
公共MyGeneric(字符串str){
//获取由“T”表示的实际类
//这只适用于MyGeneric的子类,而不适用于MyGeneric本身!
类genericType=(类)((ParameterizedType)getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
试一试{
//使用提供的参数实例化该类
instance=genericType.getConstructor(String.class).newInstance(str);
}捕获(例外e){
抛出新的IllegalArgumentException(e);
}
}
}
类MyUser扩展了MyGeneric{
公共MyUser(){
//提供用于实例化用户的字符串。。。
超级(“userStr”);
}
}
类用户{/*…*/}
编辑:使泛型类
抽象
,以强制使用子类

它还可以用于匿名类,如:

newmygeneric(“…字符串…”){}


我认为这是最接近您的初始目标…

为什么?这不允许MyGeneric使用T的方法。MyGeneric只能使用T上限的方法。
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 { /*...*/ }