转自:https://blog.csdn.net/w605283073/article/details/89221853

今天和小伙伴讨论一个mybatis-plus的一个诡异问题,最后定位到原因竟然是lombok@Data和@Builder一起用无法添加无参构造方法引起的,非常隐蔽。

很多框架都是同反射等调用无参数构造方法来创建实例的,需要注意。

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

// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available

package com.chujianyun.util;

public class Dog {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

public Dog() { /* compiled code */ }

public java.lang.String getName() { /* compiled code */ }

public java.lang.Integer getAge() { /* compiled code */ }

public java.lang.String getNickName() { /* compiled code */ }

public java.lang.String getTest() { /* compiled code */ }

public void setName(java.lang.String name) { /* compiled code */ }

public void setAge(java.lang.Integer age) { /* compiled code */ }

public void setNickName(java.lang.String nickName) { /* compiled code */ }

public void setTest(java.lang.String test) { /* compiled code */ }

public boolean equals(java.lang.Object o) { /* compiled code */ }

protected boolean canEqual(java.lang.Object other) { /* compiled code */ }

public int hashCode() { /* compiled code */ }

public java.lang.String toString() { /* compiled code */ }
}

单独使用@Builder注解,发现生成了全属性的构造方法。

package com.chujianyun.util;

public class Dog {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

Dog(java.lang.String name, java.lang.Integer age, java.lang.String nickName, java.lang.String test) { /* compiled code */ }

public static com.chujianyun.util.Dog.DogBuilder builder() { /* compiled code */ }

public static class DogBuilder {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

DogBuilder() { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder name(java.lang.String name) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder age(java.lang.Integer age) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder nickName(java.lang.String nickName) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder test(java.lang.String test) { /* compiled code */ }

public com.chujianyun.util.Dog build() { /* compiled code */ }

public java.lang.String toString() { /* compiled code */ }
}
}
@Data和@Builder一起用

@Data
@Builder
public class Dog {

private String name;

private Integer age;

private String nickName;

private String test;

}
效果

// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available

package com.chujianyun.util;

public class Dog {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

Dog(java.lang.String name, java.lang.Integer age, java.lang.String nickName, java.lang.String test) { /* compiled code */ }

public static com.chujianyun.util.Dog.DogBuilder builder() { /* compiled code */ }

public java.lang.String getName() { /* compiled code */ }

public java.lang.Integer getAge() { /* compiled code */ }

public java.lang.String getNickName() { /* compiled code */ }

public java.lang.String getTest() { /* compiled code */ }

public void setName(java.lang.String name) { /* compiled code */ }

public void setAge(java.lang.Integer age) { /* compiled code */ }

public void setNickName(java.lang.String nickName) { /* compiled code */ }

public void setTest(java.lang.String test) { /* compiled code */ }

public boolean equals(java.lang.Object o) { /* compiled code */ }

protected boolean canEqual(java.lang.Object other) { /* compiled code */ }

public int hashCode() { /* compiled code */ }

public java.lang.String toString() { /* compiled code */ }

public static class DogBuilder {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

DogBuilder() { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder name(java.lang.String name) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder age(java.lang.Integer age) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder nickName(java.lang.String nickName) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder test(java.lang.String test) { /* compiled code */ }

public com.chujianyun.util.Dog build() { /* compiled code */ }

public java.lang.String toString() { /* compiled code */ }
}
}
我们发现外层的Dog类没有了默认的构造方法。

如果手动添加无参数构造方法或者用@NoArgsConstructor注解都会报错!

@Builder
@Data
@NoArgsConstructor
public class Dog {

private String name;

private Integer age;

private String nickName;

private String test;

}

正确写法如下:

@Builder
@Data
public class Dog {

private String name;

private Integer age;

private String nickName;

private String test;

@Tolerate
Dog() {}
}

解释如下

添加函数或者构造方法,让lombok假装它不存在(不感知)。

效果如下:

package com.chujianyun.util;

public class Dog {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

Dog() { /* compiled code */ }

Dog(java.lang.String name, java.lang.Integer age, java.lang.String nickName, java.lang.String test) { /* compiled code */ }

public static com.chujianyun.util.Dog.DogBuilder builder() { /* compiled code */ }

public java.lang.String getName() { /* compiled code */ }

public java.lang.Integer getAge() { /* compiled code */ }

public java.lang.String getNickName() { /* compiled code */ }

public java.lang.String getTest() { /* compiled code */ }

public void setName(java.lang.String name) { /* compiled code */ }

public void setAge(java.lang.Integer age) { /* compiled code */ }

public void setNickName(java.lang.String nickName) { /* compiled code */ }

public void setTest(java.lang.String test) { /* compiled code */ }

public boolean equals(java.lang.Object o) { /* compiled code */ }

protected boolean canEqual(java.lang.Object other) { /* compiled code */ }

public int hashCode() { /* compiled code */ }

public java.lang.String toString() { /* compiled code */ }

public static class DogBuilder {
private java.lang.String name;
private java.lang.Integer age;
private java.lang.String nickName;
private java.lang.String test;

DogBuilder() { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder name(java.lang.String name) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder age(java.lang.Integer age) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder nickName(java.lang.String nickName) { /* compiled code */ }

public com.chujianyun.util.Dog.DogBuilder test(java.lang.String test) { /* compiled code */ }

public com.chujianyun.util.Dog build() { /* compiled code */ }

public java.lang.String toString() { /* compiled code */ }
}
}

记lombok@Data和@Builder一起用无法添加无参构造方法的坑的更多相关文章

  1. java~lombok里的Builder注解

    lombok注解在java进行编译时进行代码的构建,对于java对象的创建工作它可以更优雅,不需要写多余的重复的代码,这对于JAVA开发人员是很重要的,在出现lombok之后,对象的创建工作更提供Bu ...

  2. lombok 下的@Builder注解用法

    pom依赖 <dependency> <groupId>org.projectlombok</groupId>            <artifactId& ...

  3. 详解Lombok中的@Builder用法

    Builder 使用创建者模式又叫建造者模式.简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程. 基础使用 @Builder注释为你的类生成相对略微复杂 ...

  4. Lombok中的@Builder注解

    1.前言 今天在看项目代码的时候, 遇到了实体类上加@Builder注解, 之前在开发的时候, 一直没有用过这个注解, 便兴致勃勃地去查了一下资料, 它也是Lombok中的注解, 我们都知道Lombo ...

  5. 在项目中导入lombok依赖自动生成有参,无参 空参 方法的注解

    导入依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok< ...

  6. 使用lombok.Data编译时无法找到get/set方法

    我的IDEA版本是2019.2 在使用IDEA创建了一个SpringBoot项目,其中一个实体类使用了@Data注解,但是在Service中调用的时候找不到get/set方法. 检查步骤: 1.在St ...

  7. 记: Spring Data Jpa @OneToMany 级联查询被动触发的问题

    I have encountered a bug in using Spring Data Jpa. Specifically,when @OneToMany was used to maintain ...

  8. .net core 开车记:Data Protection Key 过期问题与登录页面访问慢

    K8s 船还没修好,.net core 车又出了问题,开着 k8s 豪华邮轮.飚着 .net core 极品飞车的好事真是多磨. 自从我们用上 .net core ,就一直被 .net core 的一 ...

  9. djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记

    情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...

随机推荐

  1. laravel框架之即时更改

    表单//@foreach($res as $k=>$v) <tr id="{{$v->id}}" > <td>{{$v->id}}< ...

  2. FreeMarker学习系列之一

    一. 基本概念 ${...}: FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式插值 FTL 标签 (FreeMarker模板的语言标签): FTL标签和HTML标签有一些相似 ...

  3. Navicat连接mysql报错1862

    昨天重新设置了mysql的密码 因为之前一直都是不用密码登录的 因为是公司数据库还是要密码 但是加了密码我今天打开 然后再控制台重新设置一下密码就好了 mysql -u root -p SET PAS ...

  4. Android 9.0网络权限适配

    在做Android开发时,使用华为的p20和平板(均为Android 9.0)测试时,发现不能使用WIFI网络,一番郁闷纠结查找后 直接上方法: 在res文件夹下创建xml文件夹,在xml里面创建文件 ...

  5. SAP里SE38设置模板

    经验丰富些的大佬们都会有一套自己的风格,比如report主程序里几个form,常见的fieldcat的宏定义,常见的一些数据定义等等. 1.使用事物代码SE38进入编辑器. 2.点击客户端最右下角的文 ...

  6. 枚举ENUM的tostring() valueof()name()和values()用法

    从jdk5出现了枚举类后,定义一些字典值可以使用枚举类型; 枚举常用的方法是values():对枚举中的常量值进行遍历; valueof(String name) :根据名称获取枚举类中定义的常量值; ...

  7. mysql 命令修复表

    如果在断电.硬重启服务器等情况下,可能会造成有些表损坏,这时就需要修复 修复表前需要将mysql停止 centos7 用 systemctl stop mysqld.service 来停止 然后进入到 ...

  8. Python3和HTMLTestRunner生成html测试报告

    1.测试环境: Python3.5+unittest+HTMLTestRunner 2.下载HTMLTestRunner.py文件 下载地址 http://tungwaiyip.info/softwa ...

  9. websocket 的基本用法

    项目当中使用到了websocket,以前的项目当中使用到了另外一个类似的socket.io,两者的区别和联系在另外一篇文章当中有提及,这里就简单的写下websocket的用法 下面的例子是阮一峰的We ...

  10. LengthFieldBasedFrameDecoder

    LengthFieldBasedFrameDecoder 详解 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -31[ 博客园 总入口 ] 文章目录 LengthFieldBasedFr ...