глубокая копия с использованием отражения java - PullRequest
0 голосов
/ 03 августа 2020

Я не могу получить контейнер из поля класса с помощью отражения. Я попробовал описанный ниже метод, но получил исключение:

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

Я не хочу использовать методы копирования через сериализацию, меня интересует отражение.

1 Ответ

1 голос
/ 03 августа 2020

Надеюсь, вы делаете это для тренировки? Если нет, тогда используйте какую-нибудь библиотеку с открытым исходным кодом, это намного сложнее, чем вы думаете - проверьте это .

Ваша проблема в том, что вы добавляете в список to, а to list - это реализация, которая не поддерживает добавление (кстати, вы игнорируете результат). Я предлагаю создать новый список и переназначить его вместо добавления к существующему.

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

Аналогичная вещь с Set - ваш текущий код для Set не имеет никакого смысла, он работает по Class объектам.

...