deep copy using reflection java

Tags: , ,



I can’t get a container from the class field using reflection. I tried the method below, but got an exception:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at java.util.Collections.addAll(Collections.java:5455)
public static void copy(Object from, Object to) throws NoSuchFieldException, IllegalAccessException {
        Class<?> fromClass = from.getClass();
        Class<?> toClass = to.getClass();
        Field[] sourceFields = fromClass.getDeclaredFields();
        for (Field fromField : sourceFields) {
            Field toField = toClass.getDeclaredField(fromField.getName());
            toField.setAccessible(true);
            fromField.setAccessible(true);
            if (fromField.getType().equals(toField.getType())) {
                if (!(fromField.getType() == String.class || fromField.getType().isPrimitive())) {
                        if (fromField.getType().isAssignableFrom(List.class)) {
                            List list = (List) fromField.get(from);
                            List list1 = (List) toField.get(to);
                            Collections.addAll(list1,list);
                            toField.set(to, fromField.get(from));
                        } else if (fromField.getType().isAssignableFrom(Set.class)) {
                            Set set = (Set) fromField.get(from);
                            Set set1 = (Set) toField.get(to);
                            set1.clear();
                            set.addAll(set1);
                            toField.set(to, fromField.get(from));
                        }
                } else {
                    toField.set(to, fromField.get(from));
                }
            }
        }
    }

I don’t want to use methods of copying via serialization, I’m interested in reflection.

Answer

You are doing this for training I hope? If not then use some opensource library, it’s a lot harder than you think – check this.

Your problem is that you are adding to the to list, and the to list is an implementation that does not support adding (btw then you are ignoring the result). I suggest creating a new list and reassiging it, instead of adding to the existing one.

List list = (List) fromField.get(from);
List list1 = (List) toField.get(to);
List newList = new ArrayList();
if(list != null)
  Collections.addAll(newList,list);
if(list1 != null)
  Collections.addAll(newList,list1);
toField.set(to, newList);

Similar thing with Set – your current code for Set doesn’t make any sense, it operates on Class objects.



Source: stackoverflow