Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

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

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. I feel like this is much related to parsing

Say there are two classes. And in both classes I have some variables, say strings (just for simplicity, variable type can be any), which have similar names.

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

    class ClassB{
        String x,y,z;
    }

Now, what i need is, i need to copy the value of one class's variable values to other classes corresponding variable.

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;

like that.

But please note that what i need is not the above method. I hope there will be a way to write a simple method, so that it will identify the relevent variable by the name passed to it. Then it will do the value assignment accordingly.

My imagined method is like this,

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

For example if you pass bb.x to assign(...) method, then it will do aa.x=bb.x assignment.

Hope this is clear enough. There must be a better way to explain this. If someone know it please edit the post(+title) to make it more clear (But save my idea)..

Please let me know if there's a way to achieve this.

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...