通过反射从实例中获取通用类型

时间:2017-04-25 01:41:40

标签: java generics

让我先谈谈可能重复的免责声明......我确实尝试了解这个主题的几个问题,但它们并不代表我对我想要实现的目标的挑战。所以请耐心地帮助解决问题。

这是我的情况: 我有一个接口(在命令模式中),如下所示,我需要一个实现。

public interface IIntelligentAction<E> {
    /**
     * Set dynamic variable for this action.
     */
     public void setDynamicOperand(Callable<?> getter);

    /*
     * Set validating operand for this action.
     */
     public void setValidatingOperand(Callable<?> getter);

    /*
     * The implementation must check if the operands (dynamic and validating) are 
     * compatible with each other for this action. 
     */
     public boolean areOperandsCompatible();

    /*
     * Execute this action.
     * <p> The implementation must check for both operands being assigned and are
     * compatible with each other, before allowing the action to execute.
     */
     public void execute();

}

界面的设计是有意的,我理解其基本原理(例如,DateCalendar在语义上兼容,但不兼容类型。

现在我关注的是areOperandsCompatible()方法。可以看出,该方法接受参数化Callable,因此通过反射我将始终看到Callable但不会返回它将返回的类型。如何访问我从setter方法得到的泛型实例的参数化类型?

1 个答案:

答案 0 :(得分:0)

我最终实现此问题的解决方案的方法是:

public Class<?> getGenericsTypeDeclared(Object any) {
        List<Type> classScope = new ArrayList<Type>();
        classScope.add(any.getClass());
        classScope.add(any.getClass().getGenericSuperclass());

        for (Type type : any.getClass().getGenericInterfaces())
            classScope.add(type);

        Class<?> genericType = null;

        for (Type type : classScope) {
            try {
                genericType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
            } catch (ClassCastException e) {
                if (logging != null)
                    logging.warn("Ignoring non-generic type: " + type);
            } catch (ArrayIndexOutOfBoundsException e) {
                if (logging != null)
                    logging.warn("Oddly Generic type without parameters. Found: " + type);
            }

            if (genericType != null) {
                return genericType.getClass();
            }
        }

        return null;
    }

该方法使用本机Java,因此不需要任何第三方库。希望它对其他寻求类似需求的人有所帮助。