¿Cómo puedo crear un constructor de Lombok para una clase de terceros (es decir, no puedo modificar su código fuente)?
Tengo una clase existente que no puedo cambiar:
public class ThirdPartyPojo { // one of many properties private String name; public ThirdPartyPojo() { // default no-args constructor } String getName() { return this.name; } void setName(String name) { this.name = name; } // many more getters and setters } Ahora me gustaría crear un @Builder para obtener una API de compilación fluida para simplificar la creación de instancias de ThirdPartyPojo con valores predeterminados.
Esto es lo que probé:
@Builder public class ThirdPartyPojoBuilder extends ThirdPartyPojo { @Default private String name = "default name"; // many more default values for other properties }El código se compila y puedo hacer referencia al constructor, por ejemplo
ThirdPartyPojo pojoWithDefaultName = ThirdPartyPojoBuilder.builder().build(); ThirdPartyPojo pojoWithCustomName = ThirdPartyPojoBuilder.builder().name("custom name").build(); System.out.println(pojoWithDefaultName.getName()); System.out.println(pojoWithCustomName.getName()); Sin embargo, esto no funciona ya que getName() devuelve un null tanto para pojoWithDefaultName como para pojoWithCustomName .
Me temo que no hay una salida fácil para que Lombok genere automáticamente el constructor de la forma que desee. Lo que hace Lombok @Builder en general es:
Finalmente, aplicar @Builder a una clase es como si agregara @AllArgsConstructor(access = AccessLevel.PACKAGE) a la clase y aplicara la anotación @Builder a este constructor de todos los argumentos.
Eso es, creo, todo lo que puedes hacer:
public class ThirdPartyPojoBuilder extends ThirdPartyPojo { @Builder public ThirdPartyPojoBuilder(String name) { this.setName(name); } }Entonces es posible, por ejemplo:
var thirdPartyPojo = ThirdPartyPojoBuilder.builder().name("A Name").build();Según la respuesta de pirho , encontré una solución factible que también respeta los valores predeterminados.
@Builder en el nivel de clase@Default y asigne valores a cualquier campo que deba tener un valor predeterminadothis.set*(...) para cada parámetro del constructorp.ej
@Builder public class ThirdPartyPojoBuilder extends ThirdPartyPojo { @Default private String name = "default name" public ThirdPartyPojoBuilder(String name) { this.setName(name); } }que también admite valores predeterminados:
ThirdPartyPojo pojoWithDefaultName = ThirdPartyPojoBuilder.builder().build(); ThirdPartyPojo pojoWithCustomName = ThirdPartyPojoBuilder.builder().name("custom name").build(); System.out.println(pojoWithDefaultName.getName()); // prints "default name" System.out.println(pojoWithCustomName.getName()); // prints "custom name"