自定义 Lombok 生成的 Builder
Customizing Builder generated by Lombok
我已经用构建器定义了一个 class,现在我想使用 Lombok 的 @Builder
注释来限制样板代码。
public class ClientApp {
private UUID clientId;
ClientApp(UUID clientId) {
this.clientId = clientId;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private UUID clientId;
public Builder clientId(String clientId) {
return clientId(UUID.fromString(clientId));
}
public Builder clientId(UUID clientId) {
this.clientId = clientId;
return this;
}
public ClientApp build() {
return new ClientApp(this.clientId);
}
}
public Builder clientId(String clientId) {
return clientId(UUID.fromString(clientId));
}
}
但是,注解不会生成clientId(String)
方法,只会生成clientId(UUID)
。如何使用 Lombok 生成它?
好吧,lombok 不会为你生成这个,但你可以使用 @Builder
并有一个 ClientAppBuilder class 包含一个接受字符串并将其路由到另一个方法的方法,即生成, 方法.可能您需要使用@Tolerate 标记您的方法,否则Lombok 将不会生成UUID 接受方法。
披露:我是 Lombok 开发人员。
我无法使用 @Tolerate
方法(我可能做错了)。
/**
* Fails with The method clientId(String) in the type So33943193.ClientApp.ClientAppBuilder is not applicable
* for the arguments (UUID)
*/
public static class ClientAppBuilder {
@Tolerate
public ClientAppBuilder clientId(String clientId) {
return this.clientId(UUID.fromString(clientId));
}
}
但是,如果您使用的是 java8,则可以解决以下事实:在使用具有默认方法的接口生成构建器方法时,lombok 仅匹配方法名称而不匹配整个签名。
package lombok.javac.handlers.Whosebug;
import static org.junit.Assert.*;
import java.util.UUID;
import lombok.Builder;
import lombok.Value;
import org.junit.Test;
public class So33943193 {
/**
* The Interface WithClientUUID.
*
* @param <BLDR> the builder type
*/
public static interface WithClientUUID<BLDR extends WithClientUUID<BLDR>> {
/**
* Client id.
*
* @param clientId the client id
* @return the bldr
*/
default BLDR clientId(String clientId) {
return this.clientId(UUID.fromString(clientId));
}
/**
* Client id.
*
* @param clientId the client id
* @return the bldr
*/
BLDR clientId(UUID clientId);
}
/**
* The Class ClientApp.
*/
@Builder(toBuilder = true)
@Value
public static class ClientApp {
/** The client id. */
private final UUID clientId;
/**
* Instantiates a new client app.
*
* @param clientId the client id
*/
ClientApp(UUID clientId) {
this.clientId = clientId;
}
/**
* Implement the builder and extend the interface.
*/
public static class ClientAppBuilder implements WithClientUUID<ClientAppBuilder> {}
}
/**
* Test all scenarios
*/
@Test
public void testClientApp() {
UUID expected = UUID.randomUUID();
final ClientApp fromUuid = ClientApp.builder()
.clientId(expected)
.build();
final ClientApp fromString = ClientApp.builder()
.clientId(expected.toString())
.build();
assertEquals(expected, fromUuid.getClientId());
assertEquals(expected, fromString.getClientId());
}
}
我已经用构建器定义了一个 class,现在我想使用 Lombok 的 @Builder
注释来限制样板代码。
public class ClientApp {
private UUID clientId;
ClientApp(UUID clientId) {
this.clientId = clientId;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private UUID clientId;
public Builder clientId(String clientId) {
return clientId(UUID.fromString(clientId));
}
public Builder clientId(UUID clientId) {
this.clientId = clientId;
return this;
}
public ClientApp build() {
return new ClientApp(this.clientId);
}
}
public Builder clientId(String clientId) {
return clientId(UUID.fromString(clientId));
}
}
但是,注解不会生成clientId(String)
方法,只会生成clientId(UUID)
。如何使用 Lombok 生成它?
好吧,lombok 不会为你生成这个,但你可以使用 @Builder
并有一个 ClientAppBuilder class 包含一个接受字符串并将其路由到另一个方法的方法,即生成, 方法.可能您需要使用@Tolerate 标记您的方法,否则Lombok 将不会生成UUID 接受方法。
披露:我是 Lombok 开发人员。
我无法使用 @Tolerate
方法(我可能做错了)。
/**
* Fails with The method clientId(String) in the type So33943193.ClientApp.ClientAppBuilder is not applicable
* for the arguments (UUID)
*/
public static class ClientAppBuilder {
@Tolerate
public ClientAppBuilder clientId(String clientId) {
return this.clientId(UUID.fromString(clientId));
}
}
但是,如果您使用的是 java8,则可以解决以下事实:在使用具有默认方法的接口生成构建器方法时,lombok 仅匹配方法名称而不匹配整个签名。
package lombok.javac.handlers.Whosebug;
import static org.junit.Assert.*;
import java.util.UUID;
import lombok.Builder;
import lombok.Value;
import org.junit.Test;
public class So33943193 {
/**
* The Interface WithClientUUID.
*
* @param <BLDR> the builder type
*/
public static interface WithClientUUID<BLDR extends WithClientUUID<BLDR>> {
/**
* Client id.
*
* @param clientId the client id
* @return the bldr
*/
default BLDR clientId(String clientId) {
return this.clientId(UUID.fromString(clientId));
}
/**
* Client id.
*
* @param clientId the client id
* @return the bldr
*/
BLDR clientId(UUID clientId);
}
/**
* The Class ClientApp.
*/
@Builder(toBuilder = true)
@Value
public static class ClientApp {
/** The client id. */
private final UUID clientId;
/**
* Instantiates a new client app.
*
* @param clientId the client id
*/
ClientApp(UUID clientId) {
this.clientId = clientId;
}
/**
* Implement the builder and extend the interface.
*/
public static class ClientAppBuilder implements WithClientUUID<ClientAppBuilder> {}
}
/**
* Test all scenarios
*/
@Test
public void testClientApp() {
UUID expected = UUID.randomUUID();
final ClientApp fromUuid = ClientApp.builder()
.clientId(expected)
.build();
final ClientApp fromString = ClientApp.builder()
.clientId(expected.toString())
.build();
assertEquals(expected, fromUuid.getClientId());
assertEquals(expected, fromString.getClientId());
}
}