Copying one class's fields into another class's identical fields

后端 未结 4 1252
耶瑟儿~
耶瑟儿~ 2021-01-02 04:23

I have this question. But it will be difficult for me to explain as I don\'t know exact terms to use. Hope someone will understand. I\'ll try to discribe to the best i can.

相关标签:
4条回答
  • new answer.

    I'd suggest looking into Dover as it seems pretty straightforward.

    The second option is serializing classes into XML and deserializing into your target class only on members that match.

    The third option I mentioned in the comment was using reflection - http://java.sun.com/developer/technicalArticles/ALT/Reflection/

    This technique allows for a nice design pattern called Introspection - Java introspection and reflection which in turn allows you to discover members of a certain class...

    Now, having said that, one would simply "discover" members of ClassA, fill a ArrayList with their names, discover members of ClassB, fill another ArrayList with their names, and copy values of the intersecting set. At least that's my idea on it.

    0 讨论(0)
  • 2021-01-02 04:55

    Look here. Just use BeanUtils.copyProperties(newObject, oldObject);

    0 讨论(0)
  • 2021-01-02 04:57

    Did you ever heared about Dozer ? : http://dozer.sourceforge.net/

    Dozer

    Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. Typically, these Java Beans will be of different complex types.

    Dozer supports simple property mapping, complex type mapping, bi-directional mapping, implicit-explicit mapping, as well as recursive mapping. This includes mapping collection attributes that also need mapping at the element level.

    Dozer allow you to map Java Beans :

    • using their names (implicit mapping), i.e mapping ClassA.x to ClassB.x
    • providing hability to map diffrent structures (explicit mapping) with different names with (quite simple) xml or annoation configuration .

    Here a XML example on the library site :

    <?xml version="1.0" encoding="UTF-8"?>
    <mappings xmlns="http://dozer.sourceforge.net"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://dozer.sourceforge.net
              http://dozer.sourceforge.net/schema/beanmapping.xsd">
              
      <mapping> 
        <class-a>org.dozer.vo.TestObject</class-a>
        <class-b>org.dozer.vo.TestObjectPrime</class-b>   
        <field>
          <a>one</a>
          <b>onePrime</b>
        </field>
      </mapping>  
    
          <!-- SNIP ... -->
    
    </mappings>
    

    This will map object org.dozer.vo.TestObject into TestObjectPrime, mapping all variable that are identicals together (like in your case) and variables TestObjectFoo.oneFoo into TestObjectFooPrime.oneFooPrime.

    Great, isn't it ?

    0 讨论(0)
  • 2021-01-02 05:00

    Dozer is fine, see Jean-Remy's answer.

    Also, if the variables have getters and setters according to the JavaBeans standard, there are a number of technologies that could help you, e.g. Apache Commons / BeanUtils

    Sample code (not tested):

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

    Update:

    If you don't have getters and setters, here's a quick hack that copies field values from one class to another as long as the fields have common names and types. I haven't tested it, but it should be OK as a starting point:

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

    Call Syntax:

    Copier.copy(sourceObject, targetObject);
    
    0 讨论(0)
提交回复
热议问题