I have a field of Map I am trying instantiate that looks like this
Map<Long, List<MyObj>>The code to convert it is this
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();
}This is related to this post I read: ClassCastException While casting List<String> to Class<?>.
targetValueTypeis a ParameterizedTypeImpl object. If I look at the value of that object in debug it looks like java.util.List(MyObj path).
How do "know" that the object is a list progromatically so I can do the conversion?
Update
This is an object factory that converts autogenerated domain objects from webservices to DTO domain objects. So the below code is generalized so that it should be able to handle any type of parameter.
2 Answers
The instantiation should look like this:
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>>(); }
} 2 I ended up with the following code
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];
}I had to get the raw type of the parameterizedTypeImple object. Then check if it was related to a list and an interface and use that as Class object.