如何从Java bean属性中提取类型参数?

时间:2015-07-29 13:56:01

标签: java reflection javabeans type-erasure

我有一个任意的Java bean,如下所示:

class SomeBean {

    public Map<String, SomeOtherBean> getOtherBeans() { ... }
    public void setOtherBeans(Map<String, SomeOtherBean> otherBeans) { ... }

}

我想用通用方法提取类型SomeOtherBean。在存在Java类型擦除的情况下,这甚至可能吗?

1 个答案:

答案 0 :(得分:0)

是的,即使在游戏中删除也是可能的。

Magnolia的TypeMappingImpl [1](GPL和Magnolia网络协议下的双重许可 )的以下实现提取了所有类型的参数,直到第一级setter方法:

private List<Class<?>> inferGenericTypes(Method method) {
    List<Class<?>> inferredTypes = new ArrayList<Class<?>>();
    Type[] parameterTypes = method.getGenericParameterTypes();
    for (Type parameterType : parameterTypes) {
        if (parameterType instanceof ParameterizedType) {
            ParameterizedType type = (ParameterizedType) parameterType;
            for (Type t : type.getActualTypeArguments()) {
                if (t instanceof ParameterizedType) {
                    // this the case when parameterized type looks like this: Collection<List<String>>
                    // we care only for raw type List
                    inferredTypes.add((Class<?>) ((ParameterizedType) t).getRawType());
                } else if (t instanceof WildcardType) {
                    WildcardType wildcardType = (WildcardType) t;
                    if (wildcardType.getUpperBounds().length > 0) {
                        // upper bounds (? extends Number)
                        inferredTypes.add((Class<?>) wildcardType.getUpperBounds()[0]);
                    } else {
                        // lower bounds (? super Number)
                        inferredTypes.add((Class<?>) wildcardType.getLowerBounds()[0]);
                    }
                } else {
                    inferredTypes.add((Class<?>) t);
                }
            }
        }
    }
    return inferredTypes;
}

[1]:来自包info.magnolia.jcr.node2bean.impl