Reputation: 347
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.
Upvotes: 0
Views: 971
Reputation: 142
There exactly is one thing you are expecting in BeanUtils from Apache. https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.9.2
BeanUtils.copyProperties(objectB, objectA);
Upvotes: 0
Reputation: 16498
Since A
and B
don't seem to have anything in common except for the coincidentally same sounding attributes, at least you didn't say that they inherit from each other, you can write your own mapper method or function. You can then call this function whenever you want to create a B
from an A
and save yourself some typing:
Function<A,B> mirrorToB = a -> B.builder()
.attriA(objectA.getAttriA())
.attriB(objectA.getAttriB())
.attriC(objectA.getAttriC())
.build();
B objectB = mirrorToB.apply(objectA);
Upvotes: 0
Reputation: 103348
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!).
Upvotes: 2