Convert java.lang.reflect.Type to Class clazz

前端 未结 6 1620
闹比i
闹比i 2021-02-12 11:43

How can I convert java.lang.reflect.Type to Class clazz?

If I have one method as next which has an argument of Class

相关标签:
6条回答
  • 2021-02-12 11:54

    If you are willing to use a library, you could use com.google.guava:guava:12+:

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

    Alternatively you could also use com.fasterxml.jackson.core:jackson-databind:2.8.x:

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

    This handles all cases correctly and you will get the type-erased class of your type.

    0 讨论(0)
  • 2021-02-12 11:55

    Did you mean this?

    public <T extends Type> void oneMethod(T clazz) {
    
    }
    
    public void someMethod(Type type) {
        oneMethod(type);
    }
    
    0 讨论(0)
  • 2021-02-12 12:00

    You have to ensure that type is an instance of Class, and then cast it.

    if (type instanceof Class) {
      Class<?> clazz = (Class<?>) type;
      otherMethod(clazz);
    }
    

    Of course, you also have to handle the case of it not being a Class.

    0 讨论(0)
  • 2021-02-12 12:09

    Andy Turner answer is correct, however if you need to retrieve a class from a type parameter this is a complete example:

    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);
    }
    
    0 讨论(0)
  • 2021-02-12 12:09

    It would be weird that a Type would be anything else than a Class... Javadoc for Type says

    All Known Implementing Classes: Class

    So unless you have special libraries that use non Class Types, you can simply cast - but you must be ready for a possible ClassCastException. Beware: Java use undocumented Type implementation to represent generics, see below.

    You can explicitely process it or not because it is an unchecked exception:

    Explicit way:

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

    Implicit way:

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

    but the current method could throw...


    EDIT per @Andy Turner's comment:

    Beware: Type type = new ArrayList<String>().getClass().getGenericSuperclass(); yields something that's a Type but not a Class. This one is a ParameterizedType, so you can use getRawType() method to find the actual class, but others might exist.

    0 讨论(0)
  • 2021-02-12 12:12

    Using generic types in runtime is a little bit tricky in Java. And I think this is a root cause of your issue.

    1) to be sure about generic in runtime we doing like this:

    class MyClass<E> {}
    

    and then:

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

    please pay attention to {} in the end. It means anonymous extends of MyClass. This is an important nuance.

    2) let`s improve MyClass to be able to extract the type in runtime.

    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);
        }
    
    }
    

    and finally, use it like this:

    MyClass<TargetType> genericAwaredMyClassInctance = new MyClass<TargetType>(){};
    
    assert(genericAwaredMyClassInctance.getGenericClass() == TargetType.class)
    
    0 讨论(0)
提交回复
热议问题