List <ClassA> listA; List <ClassB> listB;
Can I use reflection to reflect listA into listB? I got below code but only reflect an object
public static <A, B> B convert(A instance,
Class<B> targetClass) throws Exception {
B target = (B)targetClass.newInstance();
for (Field targetField : targetClass.getDeclaredFields()) {
targetField.setAccessible(true);
Field field =
instance.getClass().getDeclaredField(targetField.getName());
field.setAccessible(true);
targetField.set(target, field.get(instance));
}
return target;
}
Technically spoken, yes, but only under certain conditions. Assume, you want to convert a ClassA instance into a ClassB instance. The line of code to start the conversion would be like:
Am I correct so far?
The above code will (1) create a new ClassB object, using it's default constructor, (2) get all fields declared on ClassB (but no fields from any ClassB supertype!), (3) get the same field from ClassA and (4) set the value from aInstance to the field in the newly created ClassB instance.
So far so good.
But this will only work if and only if ClassA has exact the same fields as ClassB at minimum (it may have more fields). That's the limitation. If ClassA and ClassB do not fulfill this precondition, you'll have to catch the exceptions and handle those cases separately, like:
Same fields means: same field name and same field type (or at least a 'castable' type)
So if you have a
List<ClassA>
but need aList<ClassB>
, you could iterate through the first list, convert the List items into ClassB objects and write them to the target list.Try it.
But it is not needed. You can just add the contents of the first list to the second one:
As it seems, your two
List
s are declared with different generic types. So you will have to use unsafe casts. But it feels horribly wrong to do this. What are you actually trying to achieve? If the types of objects in the lists are supposed to be different, then why are you trying to copy them?In general the
convert
method is not likely to work (forList
s or any other type).Calling
Field.setAccessible(true)
allows read and write access to private fields but will not allow modification offinal
fields viaField.set()
(anIllegalAccessException: Field is final
exception is thrown).Depending on the implementation of
List
you are trying to copy this may prevent it from working correctly. For example, usingArrayList
such as:fails when trying to copy
serialVersionUID
.The following change to the posted code gets round this problem for
static final serialVersionUID
inArrayList
:However, the next problem is that the
convert
method is performing a shallow copy. ForList
s of different types this altered version ofconvert
may appear to work correctly but it does not convert theClassA
objects in the list toClassB
(the unchecked cast above hides this). This will likely causeClassCastException
s to be thrown later in the application.Fixing this problem can be achieved by adding another method to wrap
convert
:This will then need to be called as: