Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate and add fields between classes

Tags:

java

I was wondering if the following scenario is possible.

Having two classes (Source and Destination) where in code I could do this:

public class Source{

   private String fieldA;
   private String fieldB;

   public Source(){ ... }
}

...

public class Destination{

   public Destination(Source src){ ... }
}

Source src = new Source();
Destination dest = new Destination(src);
dest.fieldA = "test";
dest.fieldB = "test";

So what I mean here is that I have two classes, one called Source that contains (private) fields and one called Destination with no fields. After creating two objects of these classes and passing in Source into the constructor of Destination, I want to be able to duplicate/copy the fields of Source into Destination.

Could something like this be possible in Java, whether or not using Reflection? And if possible, can someone give me a minor example I can start with.

like image 246
RazorAlliance192 Avatar asked Apr 20 '26 04:04

RazorAlliance192


1 Answers

A hackish version to accomplish this is to add all fields to a Map. The fields can be copied from the source object to the destination object and the field name can be the key. Something along the lines of this:

public class FieldAccessor {
    public static class Destination {
        private final Map<String, Object> fields = new HashMap<>();

        public Destination(Object o) {
            final Set<Field> accessibleFields = Arrays.stream(o.getClass().getDeclaredFields())
                    .map(field -> {
                        field.setAccessible(true);
                        return field;
                    })
                    .collect(Collectors.toSet());

            accessibleFields.forEach(field -> {
                try {
                    fields.put(field.getName(), field.get(o));
                } catch (IllegalAccessException e) {
                    throw new IllegalStateException("Unable to access field", e);
                }
            });
        }

        public Set<String> fieldNames() {
            return fields.keySet();
        }

        public Optional<Object> fieldValue(String fieldName) {
            return Optional.ofNullable(fields.get(fieldName));
        }
    }

    public static class Source {
        private final String fieldA;
        private final Integer fieldB;
        private final int fieldC;

        public Source(String fieldA, Integer fieldB, int fieldC) {
            this.fieldA = fieldA;
            this.fieldB = fieldB;
            this.fieldC = fieldC;
        }

        public String getFieldA() {
            return fieldA;
        }

        public Integer getFieldB() {
            return fieldB;
        }

        public int getFieldC() {
            return fieldC;
        }
    }

    @Test
    public void testFields() {
        Destination destination = new Destination(new Source("Abc", 123, 456));

        destination.fieldNames().stream().forEach(fieldName -> {
            System.out.println("Fieldname: " + fieldName + ", value: " + destination.fieldValue(fieldName).get());
        });
    }
}

For more info, check out this SO.

However, this is not something I would use in real production code. Instead, I would use some sort of serialization by e.g. using Jackson.

like image 178
wassgren Avatar answered Apr 22 '26 18:04

wassgren



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!