views:

486

answers:

4

Hi.

I have a class which is basically a copy of another class.

public class A {
  int a;
  String b;
}

public class CopyA {
  int a;
  String b;
}

What I am doing is putting values from class A into CopyA before sending CopyA through a webservice call. Now I would like to create a reflection-method that basically copies all fields that are identical (by name and type) from class A to class CopyA.

How can I do this?

This is what I have so far, but it doesn't quite work. I think the problem here is that I am trying to set a field on the field I am looping through.

private <T extends Object, Y extends Object> void copyFields(T from, Y too) {

 Class<? extends Object> fromClass = from.getClass();
 Field[] fromFields = fromClass.getDeclaredFields();

 Class<? extends Object> tooClass = too.getClass();
 Field[] tooFields = tooClass.getDeclaredFields();

 if (fromFields != null && tooFields != null) {
  for (Field tooF : tooFields) {
   logger.debug("toofield name #0 and type #1", tooF.getName(), tooF.getType().toString());
   try {
    // Check if that fields exists in the other method
    Field fromF = fromClass.getDeclaredField(tooF.getName());
    if (fromF.getType().equals(tooF.getType())) {
     tooF.set(tooF, fromF);
    }
   } catch (SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (NoSuchFieldException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

  }
 }

I am sure there must be someone that has already done this somehow

A: 

Dozer

Ruben Bartelink
A: 

Yeah or the BeanUtils from Apache Jakarta.

Shaun F
+6  A: 

If you don't mind using a third party library, the excellent BeanUtils from Apache Commons will handle this quite easily, using copyProperties(Object, Object).

gregcase
A: 

The first argument to tooF.set() should be the target object (too), not the field, and the second argument should be the value, not the field the value comes from. (To get the value, you need to call fromF.get() -- again passing in a target object, in this case from.)

Most of the reflection API works this way. You get Field objects, Method objects, and so on from the class, not from an instance, so to use them (except for statics) you generally need to pass them an instance.

David Moles
Thanks for the tip David
Shervin