Search code examples
javareflectiondry

Mirror an object to another in java


Have two different classes: A and B. They have exactly the same field names. Suppose their definition is below:

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class A {
  private String attriA;
  private String attriB;
  private String attriC;
}

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class B {
  private String attriA;
  private String attriB;
  private String attriC;
}

Assume I have an instance of A, objectA, and I want to translate it into B. With all manual work, it'll look like:

B objectB = B.builder()
        .attriA(objectA.getAttriA())
        .attriB(objectA.getAttriB())
        .attriC(objectA.getAttriC())
        .build();

Question:

Seems I'm repeating those setters. Any library or approaches with which I don't have to write those repetitive setters? Feeling we may use reflection, but don't know exactly how.


Solution

  • In general, java adheres to the notion of nominal typing and not of structural typing. to bring this argument home, imagine these two interfaces:

    public interface Camera {
        public void shoot(Person target);
    }
    
    public interface Gun {
        public void shoot(Person target);
    }
    

    In a structural language, someone's going to have a really, really nasty surprise. In a nominal language, this is not a problem (and note that types are fully namespaced - they have a package name, meaning, even with homonyms you're not going to run into any problems. java.util.List and java.awt.List are in no way or form interchangible, anywhere, in the java ecosystem. Guns and Grandmas).

    Similar principle applies here: An A may look a heck of a lot like a B, but in java, an A isn't a B. In fact, A's 'attriA' field has absolutely no relation whatsoever to B's 'attriA' field. The fact that they so happen to have the same name and the same type is pure coincidence. In fact, it's an implementation detail (private API); you should be able to rename the field and no code in existence should care about that, or break.

    Hence, you shouldn't want this; it's not java-esque.

    But if you insist, possibly MapStruct can do something for you here (I wouldn't recommend it, though!).