转自: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. python高级编程——入门语法(二)

    闭包 概念:外函数outer定义一个变量a,又定义一个内函数inner,而这个内函数inner访问了外函数outer的变量a,如果需要改变外函数outer的变量a的值,则需要声明 nonlocal a ...

  2. thinkphp路由配置route.php

    路由设置配置 打开route.php  引入Route控制器类(use think\Route;) 设置路由-->  Route::rule('路由表达式','路由地址','请求类型','路由参 ...

  3. shell公共函数functions

    checkpid:检查是否已存在pid,如果有一个存在,返回0(通过查看/proc目录) daemon:启动服务 killproc:杀死某个进程 pidfileofproc:寻找某个进程的pid pi ...

  4. LDA-作为线性判别 降维 推导

    LDA 降维原理 前面对 LDA 作为作为分类器 有详细推导, 其核心就是 贝叶斯公式, 已知全概率, 求(条件概率)最大先验概率, 类似的问题. 而 LDA 如果作为 降维 的原理是: a. 将带上 ...

  5. 在K8S集群中使用busybox-dig镜像,来作DNS解析分析

    以前,判断K8S里的DNS功能是否正常时,得想很多办法. 如果有了busybox-dig镜像,则作这事就简单多了. 如下命令,直接部署 kubectl run busybox -it --image= ...

  6. Activiti6 查询由某人发起的流程请求 设置流程发起人

    发起流程时,配置activiti:initiator属性,并且在代码中: Authentication.setAuthenticatedUserId(userId); 其中,userId对应流程发起人 ...

  7. 数据库中的gt,ge,lt,le的区别

    eq相等   ne.neq不相等,   gt大于, lt小于 gte.ge大于等于   lte.le 小于等于   not非   mod求模   is [not] div by是否能被某数整除   i ...

  8. redisTemplate 键值序列化策略

    redisTemplate 键值序列化策略 RedisSerializer<T> StringRedisSerializer JdkSerializationRedisSerializer ...

  9. Resource Site

    GameDevMarket.net Collection of Music, Sound effects (sfx), 2D/3D/GUI Art. http://gaurav.munjal.us/U ...

  10. JavaScript之保留两位小数

    if (!isNumeric(fm.ChangeFee.value)) { alert("请输入正确的变更费用"); document.getElementsByName('Cha ...