Копирование полей одного класса в идентичные поля другого класса
у меня такой вопрос. Но мне будет трудно объяснить, поскольку я не знаю точных терминов для использования. Надеюсь, кто-нибудь поймет. Я постараюсь рассказать как можно лучше. Я чувствую, что это очень связано с 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);