Tienen dos clases diferentes: A y B. Tienen exactamente los mismos nombres de campo. Supongamos que su definición es la siguiente:

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

Supongamos que tengo una instancia de A, objectA, y quiero traducirla a B. Con todo el trabajo manual, se verá así:

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

Pregunta:

Parece que estoy repitiendo esos setters. ¿Alguna biblioteca o enfoques con los que no tenga que escribir esos setters repetitivos? Sintiendo que podemos usar la reflexión, pero no sabemos exactamente cómo.

0
laahaa 9 jul. 2020 a las 23:44

3 respuestas

La mejor respuesta

En general, Java se adhiere a la noción de tipificación nominal y no de tipificación estructural. Para llevar este argumento a casa, imagine estas dos interfaces:

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

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

En un lenguaje estructural, alguien va a tener una muy, realmente desagradable sorpresa. En un lenguaje nominal, esto no es un problema (y tenga en cuenta que los tipos tienen espacios de nombres completos : tienen un nombre de paquete, lo que significa que, incluso con los homónimos, no tendrá ningún problema. {{ X0}} y java.awt.List de ninguna manera o forma son intercambiables, en ninguna parte, en el ecosistema de Java. Armas y abuelas).

Un principio similar se aplica aquí: una A puede parecerse mucho a una B, pero en Java, una A no es una B. De hecho, el campo 'attriA' de A no tiene absolutamente ninguna relación con el campo 'attriA' de B. El hecho de que tengan el mismo nombre y el mismo tipo es pura coincidencia. De hecho, es un detalle de implementación (API privada); debería poder cambiar el nombre del campo y ningún código existente debería preocuparse por eso o interrumpirlo.

Por lo tanto, no deberías querer esto; No es java-esque.

Pero si insiste, posiblemente MapStruct puede hacer algo por usted aquí (¡aunque no lo recomendaría!).

2
rzwitserloot 9 jul. 2020 a las 20:52

Hay exactamente una cosa que esperas en BeanUtils de Apache. https://mvnrepository.com/artifact/commons-beanutils/commons- beanutils / 1.9.2

BeanUtils.copyProperties(objectB, objectA);
0
Minh Duy 10 jul. 2020 a las 07:17

Dado que A y B no parecen tener nada en común excepto por los mismos atributos de sonido, al menos no dijiste que se heredan entre sí, puedes escribir tu propio método de mapeador o función. A continuación, puede llamar a esta función cuando quiera crear un B a partir de un A y ahorrarse algo de tipeo:

Function<A,B> mirrorToB = a ->  B.builder()
                                 .attriA(objectA.getAttriA())
                                 .attriB(objectA.getAttriB())
                                 .attriC(objectA.getAttriC())
                                 .build();

B objectB = mirrorToB.apply(objectA);
0
Eritrean 9 jul. 2020 a las 21:39