Java Generics:在运行时访问Generic Type

Joh*_*sen 14 java generics guice type-erasure annotation-processing

我想在运行时访问声明字段的泛型类型.我之前的印象是,由于Java类型的擦除,这是不可能的.但是,情况并非如此,因为一些众所周知的框架在运行时通过反射来利用泛型类型.

例如,Guice将根据您提供的泛型类型实现Provider:

public class Injectable{

    @Inject
    private Provider<SomeType> someTypeProvider;

}
Run Code Online (Sandbox Code Playgroud)

如何通过反射API访问字段的"SomeType"泛型属性或任何此类类型/方法/等?

此外,了解如何通过Java 6 Annotation Processor API访问这些泛型类型属性也很有帮助.

谢谢.

编辑:

谢谢大家的指示.我找到了一种方法,使用haylem的链接,特别是Prenkov的文章Java Reflection:Generics.

这是我正在寻找的答案:

/**
 * @author John Ericksen
 */
public class TypeReflectionExample {

    public class SomeType{}

    public class Injectable{
        @Inject  private Provider<SomeType> someTypeProvider;
    }

    public static void main(String[] args){

        try {
            Field providerField = Injectable.class.getDeclaredField("someTypeProvider");

            Type genericFieldType = providerField.getGenericType();

            if(genericFieldType instanceof ParameterizedType){
                ParameterizedType aType = (ParameterizedType) genericFieldType;
                Type[] fieldArgTypes = aType.getActualTypeArguments();
                for(Type fieldArgType : fieldArgTypes){
                    Class fieldArgClass = (Class) fieldArgType;
                    System.out.println("fieldArgClass = " + fieldArgClass);
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

结果是:

fieldArgClass = class test.TypeReflectionExample $ SomeType

对于Methods,Constructors,Superclass扩展/实现等也可以这样做

我正在考虑haylem,因为他的帖子引导我解决这个问题,即使它没有直接回答我的问题.

hay*_*lem 15

确实,在Java中运行时通常不知道泛型,因为它们是使用Type Erasure实现的.

反映泛型?

但是,您可以提取一些有关已声明类型的有价值信息(而不是运行时对象的类型),如Ian Roberston的文章Reflecting Generics和Prenkov的文章Java Reflection:Generics中所述.

泛型和类型擦除的背景

引入泛型,同时保留源qnd二进制级别的向后兼容性,因此它们有一些限制,例如:

  • 没有至少一些仿制药支持指标(这里是所谓的钻石经营者 <>)的短手形式是不可能的,
  • 不可能在运行时检查泛型类型,因为它们必须使用Type Erasure实现.

进一步阅读