从ParameterizedTypeImpl获取List类型的类

时间:2015-06-08 20:13:54

标签: java generics reflection

我有一个Map的字段我正在尝试实例化,看起来像这样

Map<Long, List<MyObj>>

转换它的代码就是这个

ParameterizedType targetMapParameterizedType = (ParameterizedType) targetMethodMap.get(targetMethodName).getGenericParameterTypes()[0];
Class<?> mapType = targetMethodMap.get(targetMethodName).getParameterTypes()[0];
if(mapType.isInterface()) {
    newMap = new HashMap<Object, Object>();
} else {
    try {
        newMap = (Map<Object, Object>) mapType.newInstance();
    } catch(Exception e) {
        newMap = new HashMap<Object, Object>();
    }
}
Class<?> targetKeyType = null;
Class<?> targetValueType = null;
try {
    targetKeyType = (Class<?>)targetMapParameterizedType.getActualTypeArguments()[0];
} catch (ClassCastException cce) {
    cce.printStackTrace();
}
try {
    targetValueType = (Class<?>)targetMapParameterizedType.getActualTypeArguments()[1];
} catch (ClassCastException cce) {
    cce.printStackTrace();
}

这与我读过的这篇文章有关:ClassCastException While casting List<String> to Class<?>

targetValueType

是ParameterizedTypeImpl对象。如果我在调试中查看该对象的值,它看起来像java.util.List(MyObj path)。

如何“知道”该对象是一个列表,所以我可以进行转换?

更新

这是一个对象工厂,它将自动生成的域对象从Web服务转换为DTO域对象。因此下面的代码是通用的,因此它应该能够处理任何类型的参数。

2 个答案:

答案 0 :(得分:0)

实例化应如下所示:

Map<Long, List<MyObj>> newMap;

...

if(mapType.isInterface()) {
    newMap = new HashMap<Long, List<MyObj>>();
} else {
    try {
        newMap = (Map<Long, List<MyObj>>) mapType.newInstance();
    } catch(Exception e) {
        newMap = new HashMap<Long, List<MyObj>>();
    }
}

答案 1 :(得分:0)

我最终得到以下代码

ParameterizedType targetMapParameterizedType = (ParameterizedType) targetMethodMap.get(targetMethodName).getGenericParameterTypes()[0];
Class<?> mapType = targetMethodMap.get(targetMethodName).getParameterTypes()[0];
if(mapType.isInterface()) {
    newMap = new HashMap<Object, Object>();
} else {
    try {
        newMap = (Map<Object, Object>) mapType.newInstance();
    } catch(Exception e) {
        newMap = new HashMap<Object, Object>();
    }
}
Class<?> targetKeyType = null;
Class<?> targetValueType = null;
try {
    targetKeyType = (Class<?>)targetMapParameterizedType.getActualTypeArguments()[0];
} catch (ClassCastException cce) {
    cce.printStackTrace();
}

if(targetMapParameterizedType.getActualTypeArguments()[1] instanceof ParameterizedType) {

ParameterizedType paramTypeImpl = (ParameterizedType) targetMapParameterizedType.getActualTypeArguments()[1];
Class<?> containerParam = (Class<?>) paramTypeImpl.getRawType();

if(containerParam.isInstance(new ArrayList<>()) && containerParam.isInterface()) {

    containerParam = new ArrayList<>().getClass();
    }
    targetValueType = containerParam;
} else {
    targetValueType = (Class<?>)targetMapParameterizedType.getActualTypeArguments()[1];
}

我必须获取parameterizedTypeImple对象的原始类型。然后检查它是否与列表和接口相关,并将其用作Class对象。