前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java.lang.Illegalaccessexception 或 java.lang.NoSuchMethodError

Java.lang.Illegalaccessexception 或 java.lang.NoSuchMethodError

原创
作者头像
AlbertZhang
修改2020-09-16 14:31:56
8980
修改2020-09-16 14:31:56
举报
文章被收录于专栏:技术文献技术文献

lombok@Data和@Builder一起用无法添加无参构造方法的坑

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

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

单独使用@Data注解,编译后的类文件会生成无参数构造方法(这并不是@Data提供的特性,而是Java自带的特性)。

   // 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@Builderpublic 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@NoArgsConstructorpublic class Dog {     private String name;     private Integer age;     private String nickName;     private String test; }

正确写法如下:

@Builder@Datapublic 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 */ }    }}

完美。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • lombok@Data和@Builder一起用无法添加无参构造方法的坑
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档