2017-06-18 109 views
0

我想分析MyComponent类中声明的字段变量,我想获取GenericDeclartion的字段类的类型,而不是它在MyComponent中声明的类型。演示如下。如何使用Java反射从ParameterizedType获取GenericDeclaration的类型?

public class SomeConfig<OP extends Operation> { 
    private OP operation; 

    public SomeConfig(OP op) { 
     this.operation = op; 
    } 
} 

public class MyComponent { 
    private SomeConfig<?> config; 

    public MyComponent(SomeConfig<?> config) { 
     this.config = config; 
    } 
} 

public class MyAnalysis { 
    public static void main(String[] args) { 
     Class clazz = MyComponent.class; 
     Field[] fields = clazz.getDeclaredFields(); 
     for (Field f : fields) { 
      Type type = f.getGenericType(); 
      if(type instanceof ParameterizedType) { 
       ParameterizedType pType = (ParameterizedType)type; 
       System.out.println(pType.getActualTypeArguments()[0]); // which prints "?" for sure 
      } 
     } 
    } 
} 

的问题:打印结果是 “?”当然。但我只想要打印Operation的类型而不是“?”。它可以实现吗?

回答

3

但我要的是得到

泛型编译后删除,因此,你不能在运行时访问他们以这种方式操作

的类型。

为了实现你的需要,你可以为了通过参数化类型的类实例改变SomeConfig构造:

public class SomeConfig<OP extends Operation> { 
    private OP operation; 
    private Class<OP> clazz; 

    public SomeConfig(OP op, Class<OP> clazz) { 
     this.operation = op; 
     this.clazz = clazz; 
    } 
} 

现在clazz场可以用来知道类的类型。

+0

还有['TypeToken'](http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/reflect/TypeToken.html),特别是[此构造函数] (http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/reflect/TypeToken.html#TypeToken-java.lang.Class-),但是“TypeToken”不是魔术,并且可能会或可能不会为OP所做的工作。 'TypeToken'需要1.一个具体的*非泛型*类型参数(否则'tt.getType()'不会返回一个'Class'),2.一个子类,显式或隐式,以及3.提供的类型参数if到超类的'extends'子句。 – Radiodef

+0

我不太熟悉番石榴。我更详细地看'TypeToken'。 'TypeToken(类 declaringClass)'似乎做同样的事情:将类实例存储在'TypeToken'中(正如你所说的那样没有魔力)。如果我理解的很好,它可以做同样的事情,但不需要向构造函数中添加类参数,因为TypeToken在声明类中实例化时将完成类型捕获:'new TypeToken (getClass())'... – davidxxx

+0

....它似乎真的是一个很好的解决方案,因为它不会改变泛型类的构造函数签名。但是,添加一个特定的库(目前无法使用)并提供一个空的匿名类来捕获类型(当您阅读代码时可能看起来令人惊讶),但这是一个需要考虑的因素。无论如何谢谢你的这些信息。真的很有用。 – davidxxx