Копирование полей одного класса в идентичные поля другого класса

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

скажем, есть два класса. И в обоих классах у меня есть некоторые переменные, скажем строки (просто для простоты, тип переменной может быть любым), которые имеют похожие имена.

Eg:
    class ClassA{
        String x,y,z;
    }

    class ClassB{
        String x,y,z;
    }

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

Eg:
    ClassA aa=new ClassA();
    ClassB bb=new ClassB();
    //set bb's variables
    aa.x=bb.x;
    aa.y=bb.y;
    aa.z=bb.z;

подобное.

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

мой воображаемый метод таков,

void assign(String val){        
    // aa.<val>=val
}

например, если вы проходите bb.x до assign(...) метод, то это будет делать aa.x=bb.x задание.

надеюсь, это достаточно ясно. Должен быть лучший способ объяснить это. Если кто-то знает, пожалуйста, отредактируйте сообщение(+название), чтобы сделать его более ясным (но сохраните мою идею)..

пожалуйста, дайте мне знать, если есть способ достичь этого.

спасибо!

4 ответов


Dozer в порядке, см. ответ Жан-Реми.

кроме того, если переменные имеют геттеры и сеттеры в соответствии со стандартом JavaBeans, существует ряд технологий, которые могут вам помочь, например Apache Commons / BeanUtils

пример кода (не проверял):

final Map<String, Object> aProps = BeanUtils.describe(a);
final Map<String, Object> bProps = BeanUtils.describe(b);
aProps.keySet().retainAll(bProps.keySet());
for (Entry<String, Object> entry : aProps.entrySet()) {
    BeanUtils.setProperty(b,entry.getKey(), entry.getValue());
}

обновление:

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

public final class Copier {

    public static void copy(final Object from, final Object to) {
        Map<String, Field> fromFields = analyze(from);
        Map<String, Field> toFields = analyze(to);
        fromFields.keySet().retainAll(toFields.keySet());
        for (Entry<String, Field> fromFieldEntry : fromFields.entrySet()) {
            final String name = fromFieldEntry.getKey();
            final Field sourceField = fromFieldEntry.getValue();
            final Field targetField = toFields.get(name);
            if (targetField.getType().isAssignableFrom(sourceField.getType())) {
                sourceField.setAccessible(true);
                if (Modifier.isFinal(targetField.getModifiers())) continue;
                targetField.setAccessible(true);
                try {
                    targetField.set(to, sourceField.get(from));
                } catch (IllegalAccessException e) {
                    throw new IllegalStateException("Can't access field!");
                }
            }
        }
    }

    private static Map<String, Field> analyze(Object object) {
        if (object == null) throw new NullPointerException();

        Map<String, Field> map = new TreeMap<String, Field>();

        Class<?> current = object.getClass();
        while (current != Object.class) {
            for (Field field : current.getDeclaredFields()) {
                if (!Modifier.isStatic(field.getModifiers())) {
                    if (!map.containsKey(field.getName())) {
                        map.put(field.getName(), field);
                    }
                }
            }
            current = current.getSuperclass();
        }
        return map;
    }
}

Синтаксис Вызова:

Copier.copy(sourceObject, targetObject);

новый ответ.

Я бы предложил взглянуть на Дувр, поскольку это кажется довольно простым.

второй вариант-сериализация классов в XML и десериализация в целевой класс только для соответствующих членов.

третий вариант, который я упомянул в комментарии, использовал отражение -http://java.sun.com/developer/technicalArticles/ALT/Reflection/

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

теперь, сказав Это, можно просто "обнаружить" членов ClassA, заполнить ArrayList их именами, обнаружить членов ClassB, заполнить другой ArrayList их именами и скопировать значения пересекающегося множества. По крайней мере, это моя идея.


посмотреть здесь. Просто используйте BeanUtils.copyProperties(newObject, oldObject);