【问题标题】:Getting List type of class from ParameterizedTypeImpl从 ParameterizedTypeImpl 获取类的列表类型
【发布时间】:2015-06-10 02:45:46
【问题描述】:

我有一个我正在尝试实例化的 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 域对象。所以下面的代码是通用的,所以它应该能够处理任何类型的参数。

【问题讨论】:

    标签: java generics reflection


    【解决方案1】:

    实例化应该如下所示:

    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>>();
        }
    }
    

    【讨论】:

    • 我不能这样做,因为这需要是通用的。
    • @lowlyone 好的,那么您应该将 newMap 的声明更改为 Map newMap;
    【解决方案2】:

    我最终得到了以下代码

    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 对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 2016-11-13
      相关资源
      最近更新 更多