将java.lang.reflect.Type转换为Class <t> clazz

时间:2016-08-04 08:11:59

标签: java generics

如何将java.lang.reflect.Type转换为Class<T> clazz

如果我有一个参数为Class<T>的下一个方法:

public void oneMethod(Class<T> clazz) {     
    //Impl
}

然后另一种方法,其参数为java.lang.reflect.Type,并且调用oneMethod(Class<T> clazz),为此我需要将java.lang.reflect.Type type转换为Class<T>

public void someMehtod(java.lang.reflect.Type type) {
   // I want to pass type arg to other method converted in Class<T>
   otherMethod(¿How to convert java.lang.reflect.Type to Class<T>?);
}

有可能吗?

6 个答案:

答案 0 :(得分:11)

您必须确保typeClass的实例,然后将其投射。

if (type instanceof Class) {
  @SuppressWarnings("unchecked")
  Class<?> clazz = (Class<?>) type;
  otherMethod(clazz);
}

当然,您还必须处理不是Class的情况。

答案 1 :(得分:1)

如果您愿意使用一个库,则可以使用com.google.guava:guava:12+

Class<?> clazz = com.google.common.reflect.TypeToken.of(type).getRawType();

或者,您也可以使用com.fasterxml.jackson.core:jackson-databind:2.8.x

Class<?> clazz = com.fasterxml.jackson.databind.type.TypeFactory.rawClass(type);

这可以正确处理所有情况,您将获得该类型的已擦除类型的类。

答案 2 :(得分:0)

TypeClass之外的任何内容都是奇怪的... Type的Javadoc说

  

所有已知的实施类:       班级

因此,除非您有使用非Class Type的特殊库,否则您可以简单地进行投射 - 但您必须为可能的ClassCastException做好准备。 注意:Java使用未记录的Type实现来表示泛型,见下文。

您可以明确地处理它,因为它是一个未经检查的例外:

明确的方式:

try {
    Class<?> clazz = (Class<?>) type;
}
catch (ClassCastException ex) {
    // process exception
}

隐含的方式:

Class<?> clazz = (Class<?>) type;

但是当前的方法可能会抛出......

编辑@Andy Turner的评论:

注意:Type type = new ArrayList<String>().getClass().getGenericSuperclass();会产生类型但不是类的东西。这个是ParameterizedType,因此您可以使用getRawType()方法查找实际的类,但其他可能存在。

答案 3 :(得分:0)

安迪·特纳(Andy Turner)的答案是正确的,但是,如果您需要从类型参数中检索类,则这是一个完整的示例:

private static class MyClass extends ArrayList<Integer> {
}

public static void main(String[] args) {

    ParameterizedType arrayListWithParamType
            = (ParameterizedType) MyClass.class.getGenericSuperclass();

    Type integerType = arrayListWithParamType.getActualTypeArguments()[0];

    Class<?> integerClass = (Class<?>) integerType;

    System.out.println(integerClass == Integer.class);
}

答案 4 :(得分:0)

在运行时中使用通用类型在Java中有点棘手。我认为这是您问题的根本原因。

1)为了确定运行时中的泛型,我们这样做:

class MyClass<E> {}

然后:

MyClass<TargetType> genericAwaredMyClassInctance = new MyClass<TargetType>(){};

请最后注意{} 。这意味着MyClass的匿名扩展。这是一个重要的细微差别。

2)让我们改进MyClass以便能够在运行时提取类型。

class MyClass<E> {

    @SuppressWarnings("unchecked")
    protected Class<E> getGenericClass() throws ClassNotFoundException {
        Type mySuperclass = getClass().getGenericSuperclass();
        Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
        String className = tType.getTypeName();

        return (Class<E>) Class.forName(className);
    }

}

最后,像这样使用它:

MyClass<TargetType> genericAwaredMyClassInctance = new MyClass<TargetType>(){};

assert(genericAwaredMyClassInctance.getGenericClass() == TargetType.class)

答案 5 :(得分:-3)

你的意思是?

public <T extends Type> void oneMethod(T clazz) {

}

public void someMethod(Type type) {
    oneMethod(type);
}
相关问题