Lombok的@Builder注解使用注意

背景:

业务运行过程中,发现使用 Lombok的@Builder以及 @Data 共同标注的类,使用反射的时候报错。找不到无参构造方法。

 

@Data和@Builder 共同使用导致无参构造丢失

  • 单独使用@Data注解,会生成无参数构造方法。

  • 单独使用@Builder注解,生成全属性的构造方法,无无参构造方法。

  • @Data和@Builder一起用:没有了默认的构造方法。手动添加无参数构造方法或者用@NoArgsConstructor注解会报错

于是看了一下 Lombok 的 @Builder 注解源码,大致看了一下,会发现源码注解里是可以看到 无参构造没有这个细节的,但是细节很容易忽略

没有去深究它的原理,毕竟也只是一个可有可无的插件。如果仔细看一下 @Builder 的注释,会发现是没有无参构造的。
原因深究的话,可以看一下 https://projectlombok.org/features/Builder

<pre>
 * &#064;Builder
 * class Example&lt;T&gt; {
 * 	private T foo;
 * 	private final String bar;
 * }
 * </pre>
 * 
 * After:
 * 
 * <pre>
 * class Example&lt;T&gt; {
 * 	private T foo;
 * 	private final String bar;
 * 	
 * 	private Example(T foo, String bar) {
 * 		this.foo = foo;
 * 		this.bar = bar;
 * 	}
 * 	
 * 	public static &lt;T&gt; ExampleBuilder&lt;T&gt; builder() {
 * 		return new ExampleBuilder&lt;T&gt;();
 * 	}
 * 	
 * 	public static class ExampleBuilder&lt;T&gt; {
 * 		private T foo;
 * 		private String bar;
 * 		
 * 		private ExampleBuilder() {}
 * 		
 * 		public ExampleBuilder foo(T foo) {
 * 			this.foo = foo;
 * 			return this;
 * 		}
 * 		
 * 		public ExampleBuilder bar(String bar) {
 * 			this.bar = bar;
 * 			return this;
 * 		}
 * 		
 * 		&#064;java.lang.Override public String toString() {
 * 			return "ExampleBuilder(foo = " + foo + ", bar = " + bar + ")";
 * 		}
 * 		
 * 		public Example build() {
 * 			return new Example(foo, bar);
 * 		}
 * 	}
 * }

解决方式:

lombok 提供了另一个注解:

这个注解的释义也是很有意思的。

Put on any method or constructor to make lombok pretend it doesn't exist,
 i.e., to generate a method which would otherwise be skipped due to possible conflicts.

这个注解可以在任何方法或者构造器上使用,这样可以使 lombok 假装这个方法或者构造器不存在。以此来达到生成由于可能存在的冲突导致跳过的方法。

package lombok.experimental;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Put on any method or constructor to make lombok pretend it doesn't exist,
 * i.e., to generate a method which would otherwise be skipped due to possible conflicts.
 */
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.SOURCE)
public @interface Tolerate {
}

于是,可以在 使用@Data和@Builder 修饰的类里加上一个@Tolerate标注的无参构造方法。

 

总结:

使用一个工具的时候,还是要看一下使用说明。想当然的使用可能会造成不可预估的损失。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值