如何获得泛型类型T的类实例

孤街浪徒 提交于 2019-12-26 19:41:55

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

我有一个泛型类Foo<T> 。 在Foo的方法中,我想获取类型T的类实例,但是我无法调用T.class

使用T.class绕过它的首选方法是什么?


#1楼

我在抽象的泛型类中遇到了这个问题。 在这种情况下,解决方案更简单:

abstract class Foo<T> {
    abstract Class<T> getTClass();
    //...
}

然后在派生类上:

class Bar extends Foo<Whatever> {
    @Override
    Class<T> getTClass() {
        return Whatever.class;
    }
}

#2楼

这是可能的:

class Foo<T> {
  Class<T> clazz = (Class<T>) DAOUtil.getTypeArguments(Foo.class, this.getClass()).get(0);
}

您需要svn / trunk / dao / src / main / java / com / googlecode / genericdao / dao / DAOUtil.java中的两个函数

有关更多说明,请参见反映泛型


#3楼

假设您有一个通用的抽象超类:

public abstract class Foo<? extends T> {}

然后是第二个类,它使用扩展T的通用Bar扩展了Foo:

public class Second extends Foo<Bar> {}

您可以获取类Bar.class通过选择在Foo类Type (从BERT bruynooghe答案),并使用infering它Class的实例:

Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
//Parse it as String
String className = tType.toString().split(" ")[1];
Class clazz = Class.forName(className);

您必须注意,此操作并不理想,因此最好缓存计算的值,以避免对此进行多次计算。 典型用途之一是在通用DAO实现中。

最终实现:

public abstract class Foo<T> {

    private Class<T> inferedClass;

    public Class<T> getGenericClass(){
        if(inferedClass == null){
            Type mySuperclass = getClass().getGenericSuperclass();
            Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
            String className = tType.toString().split(" ")[1];
            inferedClass = Class.forName(className);
        }
        return inferedClass;
    }
}

从其他函数的Foo类或Bar类调用时,返回的值为Bar.class。


#4楼

   public <T> T yourMethodSignature(Class<T> type) {

        // get some object and check the type match the given type
        Object result = ...            

        if (type.isAssignableFrom(result.getClass())) {
            return (T)result;
        } else {
            // handle the error
        }
   }

#5楼

这是一个可行的解决方案:

@SuppressWarnings("unchecked")
private Class<T> getGenericTypeClass() {
    try {
        String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
        Class<?> clazz = Class.forName(className);
        return (Class<T>) clazz;
    } catch (Exception e) {
        throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");
    }
} 

注意: 只能用作超类

  1. 必须使用类型化类扩展( Child extends Generic<Integer>Child extends Generic<Integer>

要么

  1. 必须创建为匿名实现( new Generic<Integer>() {};
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!