Reputation: 13655
I have a Field f, after I check it and it turns out that it is of type List, I can get its generic type.
But how do I create a new List with this generic type and put new instances inside?
if (List.class.isAssignableFrom(f.getType())) {
Type genericType = f.getGenericType();
List<genericType> a = new ArrayList(); // ?????? Error
}
For example I have a field with type List<MyObject>
Is it possible to create an new instance of ArrayList<MyObject>
through reflections?
Upvotes: 5
Views: 5497
Reputation: 6907
This is how I was able to create a list,
// Get the class from the type
Class fieldClass = Class.forName(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0].getTypeName());
// Create a new instance
Object instance = fieldClass.newInstance();
return List.of(instance);
Upvotes: 1
Reputation: 10266
What I normally do is:
public void populateListAndSetToField(Field field,Class<?> type, Object instance, Object... params) throws IllegalArgumentException, IllegalAccessException {
List<?> list = getGenericList(type, params);
field.set(instance, list);
}
private <Type> List<Type> getGenericList(Class<Type> type, Object... params) {
List<Type> l = new ArrayList<Type>();
for (int i = 0; i < params.length; i++) {
l.add((Type) params[i]);
}
return l;
}
There are runtime constrains and checks you need to apply but I've used this too many times and it works, thing is when I get to these implementations, the entire surrounding architecture relay on unknown object types, it is tricky.
Upvotes: 6
Reputation: 3414
You can't do that at runtime. The best you could do is to create a List<?> and do runtime type checking yourself.
If you're curious why this is, check out "type erasure". http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
Alternatively, you could attempt to clone the old list, but only the implementations of list have a clone() method, not the List interface, and it will only perform a shallow copy.
Good luck!
Upvotes: 5