java中如何将带有泛型的Type转换为Class?

pix*_*xel 3 java generics reflection types spring-properties

我有一个方法对象。

我想Type用泛型提取 return 并将其转换为 aClass以便将此类信息传递到 Spring 中PropertyResolver

Type type = myMethod.getGenericReturnType();
Class<?> returnType = /* ??? */;
environment.getProperty(key, returnType);
Run Code Online (Sandbox Code Playgroud)

Val*_*ano 5

实际上,返回Type实例必须是以下之一:(Class例如String)、GenericArrayType(例如String[]T[]List<T>[]TypeVariable(例如T)或ParametrizedType(例如List<String>List<T>)。另外Type也可以WildcardType(例如?in List<?>),但这些不能直接用作返回类型。

下面的代码尝试根据这 5 个子接口来解析给定实例的类。很少有 aType不会扩展 5 个中的任何一个,在这种情况下,我们只是说我们不能继续处理 an UnsupportedOperationException。例如,您可以创建自己的综合Type扩展类,但为什么要这样做呢?

public static Class<?> type2Class(Type type) {
    if (type instanceof Class) {
       return (Class<?>) type;
    } else if (type instanceof GenericArrayType) {
       // having to create an array instance to get the class is kinda nasty 
       // but apparently this is a current limitation of java-reflection concerning array classes.
       return Array.newInstance(type2Class(((GenericArrayType)type).getGenericComponentType()), 0).getClass(); // E.g. T[] -> T -> Object.class if <T> or Number.class if <T extends Number & Comparable>
    } else if (type instanceof ParameterizedType) {
       return type2Class(((ParameterizedType) type).getRawType()); // Eg. List<T> would return List.class
    } else if (type instanceof TypeVariable) {
       Type[] bounds = ((TypeVariable<?>) type).getBounds();
       return bounds.length == 0 ? Object.class : type2Class(bounds[0]); // erasure is to the left-most bound.
    } else if (type instanceof WildcardType) {
       Type[] bounds = ((WildcardType) type).getUpperBounds();
       return bounds.length == 0 ? Object.class : type2Class(bounds[0]); // erasure is to the left-most upper bound.
    } else { 
       throw new UnsupportedOperationException("cannot handle type class: " + type.getClass());
    }
} 
Run Code Online (Sandbox Code Playgroud)

请注意,该代码未经测试,因此可能包含编译错误。另外,我不确定它GenericArrayType对于多维数组类型的行为如何T[][](也许它会返回Object[]而不是Object[][]如果<T>我们需要在这里做额外的工作)。如果需要任何更正,请告诉我。

最后,我们在这里尝试做的是计算 Erasure 类,Type我想知道是否有一些“标准”代码可以做到这一点,也许是 Sun/Oracle 编译器或代码分析器工具的一部分,您可以使用它们实用程序并省去编码和维护的麻烦...我没有通过快速查看找到任何内容。