【问题标题】:How to get the Type of GenericDeclaration from ParameterizedType using Java Reflection?如何使用 Java 反射从 ParameterizedType 获取 GenericDeclaration 的类型?
【发布时间】:2017-11-20 18:32:39
【问题描述】:

我想分析MyComponent类中声明的字段变量,我想获取该字段类的GenericDeclartion类型,而不是MyComponent中声明的类型。演示如下。

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 的类型而不是“?”。可以实现吗?

【问题讨论】:

    标签: java generics reflection parameterized-types


    【解决方案1】:

    但我想要的只是获取操作的类型

    泛型在编译后会被删除,因此您无法在运行时以这种方式访问​​它们。

    为了满足您的需要,您可以更改 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 字段可用于了解类型的类。

    【讨论】:

    • 还有TypeToken,特别是this constructor,但TypeToken 并不神奇,可能适用于OP 正在做的事情,也可能不起作用。 TypeToken 需要 1. 一个具体的 non-generic 类型参数(否则 tt.getType() 不会返回 Class),2. 一个子类,显式或隐式和 3. 类型参数提供为if 到 extends 子句到超类。
    • 我不太了解番石榴。我看了更详细的TypeTokenTypeToken(Class&lt;?&gt; declaringClass) 似乎在做同样的事情:将类实例存储在 TypeToken 中(没有你说的魔法)。如果我理解得很好,它允许做同样的事情,但不向构造函数添加类参数,因为类型捕获将在声明类中实例化 TypeToken 时完成:new TypeToken&lt;OP&gt;(getClass())....
    • ....这似乎是一个不错的解决方案,因为它不会破坏泛型类的构造函数签名。然而,添加一个特定的库(现在不能使用)并提供一个空的匿名类来捕获类型(当您阅读代码时可能看起来令人惊讶)是一个权衡考虑。无论如何,谢谢你提供这些信息。真的很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 2014-07-07
    • 2020-05-31
    相关资源
    最近更新 更多