使用@Builder导致的无法创建无参构造方法

1. 前言

  1. 在创建实体类的时候,有时候参数过于多,如果使用有参数的构造函数,实在看起来不是很优雅,一般都会想使用@Builder构建者模式来进行创建对象,不仅仅优雅,而且还方便。
  2. 当偶然机会发现,如果使用了@Builder,该实体类会失去无参构造方法
  3. 具体现象如下:
    当不加任何注解的时候,完成正常:
    在这里插入图片描述
    当加了@Builder的时候,则会直接出现下面的错误,提示没有无参的构造函数:
    在这里插入图片描述

2. 先说结论

  1. 由于没有时间深入查看@Builder的源码,但是可以从编译之后的字节码得出结论:
    1. 实体类使用了@Builder,会有全参构造函数,没有默认无参构造函数,即无法使用默认无参构造函数。
    2. 解决方法:
      1. 在实体类上同时加上:@Builder、@AllArgsConstructor、@NoArgsConstructor

      2. 手写全部有参构造方法,以及 无参构造方法

      3. 手写个默认无参构造方法,并加上@Tolerate

        @Builder
        public class demoBuilderEntry {
            private String name;
            private String sex;
        
            @Tolerate
            public demoBuilderEntry() {
            }
        }
        

3. 演示

  1. 若不知道怎么查看java反编译字节码内容,可以看一下:
    Java 如何进行反编译生成.java文件(javap、jad下载安装使用)

  2. 当实体类不加任何东西:

    public class demoBuilderEntry {
        private String name;
        private String sex;
    }
    

    可以看见是默认有无参构造函数

    public class demoBuilderEntry {
    
        public demoBuilderEntry() {
        }
    
        private String name;
        private String sex;
    }
    
  3. 当实体类加上@Builder注解:

    @Builder
    public class demoBuilderEntry {
        private String name;
        private String sex;
    }
    

    可以看出:无参构造函数已不存在,只剩全参构造函数

    public class demoBuilderEntry {
        public static class demoBuilderEntryBuilder {
    
            public demoBuilderEntryBuilder name(String name) {
                this.name = name;
                return this;
            }
    
            public demoBuilderEntryBuilder sex(String sex) {
                this.sex = sex;
                return this;
            }
    
            public demoBuilderEntry build() {
                return new demoBuilderEntry(name, sex);
            }
    
            public String toString() {
                return (new StringBuilder()).append("demoBuilderEntry.demoBuilderEntryBuilder(name=").append(name).append(", sex=").append(sex).append(")").toString();
            }
    
            private String name;
            private String sex;
    
            demoBuilderEntryBuilder() {
            }
        }
    
        demoBuilderEntry(String name, String sex) {
            this.name = name;
            this.sex = sex;
        }
    
        public static demoBuilderEntryBuilder builder() {
            return new demoBuilderEntryBuilder();
        }
    
        private String name;
        private String sex;
    }
    
    

    因此,如下图,一定会报错:
    在这里插入图片描述

    有人会说:没有无参怎么了,也没有什么事情,反正需要构造。
    但像spring这种,我们可以从配置文件中注入属性,如@ConfigurationProperties,它们的做法是先创建该类对象,使用无参构造函数,然后再调用set方法,此时,你没有默认无参构造方法,必然会失败,毕竟连对象都没有创建成功。
    具体失败案例可以看:实体类使用@Builder,导致@ConfigurationProperties注入属性失败

  4. 如果需要无参构造函数,那就手动添加,在实体类上,再加上@NoArgsConstructor也无效。
    根据下图可以看见,似乎没有报错
    在这里插入图片描述

    当运行的时候,则报错如下:与实际参数列表不符,显然是无法通过加@NoArgsConstructor创建默认无参构造函数
    在这里插入图片描述

4. 解决方法

1. 在实体类上再加上@AllArgsConstructor即可

  1. 根据下图查看,似乎也没有问题:
    在这里插入图片描述

  2. 点击运行,查看结果的时候,居然可以运行成功如下:
    在这里插入图片描述

  3. 反手我们去看一下反编译:

    
    public class demoBuilderEntry {
        public static class demoBuilderEntryBuilder {
            // builder 的代码省略,没有粘出来
        }
        
        public static void main(String args[]) {
            System.out.println(new demoBuilderEntry());
        }
    
        public static demoBuilderEntryBuilder builder() {
            return new demoBuilderEntryBuilder();
        }
    
        public demoBuilderEntry(String name, String sex) {
            this.name = name;
            this.sex = sex;
        }
    	// 无参构造函数有了
        public demoBuilderEntry() {
        }
    
        private String name;
        private String sex;
    }
    
    

2. 手写个无参构造函数并加上@Tolerate

  1. @Tolerate:中文:容许,通俗来说,被该注解加上的方法,让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.
     */
    @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Tolerate {
    }
    
  2. 测试:
    在这里插入图片描述

3. 手写有参无参构造方法

  1. 这种方法是最简单粗暴的,但是代码可能会没有那么简洁:
    在这里插入图片描述
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 如果WindowBuilder的Design面板空白,可能是由于以下原因: 1. 安装的WindowBuilder插件版本与Eclipse版本不兼容。 2. WindowBuilder插件已损坏或失效。 3. 操作系统的环境问题。 如果想解决这个问题,可以尝试以下操作: 1. 卸载并重新安装WindowBuilder插件。 2. 安装最新版本的Eclipse。 3. 尝试在不同的操作系统中运行Eclipse和WindowBuilder。 ### 回答2: WindowBuilder是一个强大的Eclipse插件,可以帮助开发者在Eclipse中进行GUI界面设计。在使用WindowBuilder时,如果出现design空白的情况,可能是以下几种原因导致的: 1. WindowBuilder插件未正确安装或配置。在使用WindowBuilder前,需要确保已将其正确地安装到Eclipse中,并配置好相关的参数。如果插件未正确安装或配置,则可能出现问题。 2. JDK版本不匹配。WindowBuilder需要使用较新的JDK版本才能正常工作。如果使用的JDK版本过旧或与Eclipse不兼容,则可能导致design空白。 3. 插件版本过旧。如果使用的WindowBuilder插件版本过旧,则可能无法正常运行或出现故障。需要及时更新插件以保证其正常工作。 4. 代码错误。在设计GUI界面时,可能会出现代码错误,导致界面无法正常显示。需要检查代码是否出现语法错误,或者是否使用了不支持的特性。 5. 系统兼容性问题。有时,WindowBuilder的design空白问题可能是由于操作系统的兼容性问题所导致的。这时需要调整操作系统的设置或更新最新的系统补丁以解决问题。 针对以上问题,我们可以采取以下方法来解决: 1. 检查和更新插件。首先需要检查和更新WindowBuilder插件,确保插件版本正确并配置好相关参数。 2. 检查JDK版本。检查JDK版本是否过旧或与Eclipse不兼容,并相应地进行更新或调整。 3. 检查代码。在设计GUI界面时,要注意检查代码是否存在语法错误,或者是否使用了不支持的特性。 4. 检查系统设置。如果WindowBuilder的design空白问题是由于系统兼容性问题导致的,则需要检查和调整操作系统设置或更新最新的系统补丁。 ### 回答3: windowbuilder是一款强大的Java GUI设计工具,它可以使我们更加方便快捷地进行Swing界面的开发。而在使用windowbuilder时,有时我们会遇到设计界面空白的情况,下面我来简单介绍一下可能会导致这种问题的原因和解决方法。 造成windowbuilder的design空白的原因: 1.资源文件的配置问题:有时候,我们在创建工程时没有正确配置相关的资源文件,导致工程无法正常运行。 2.编码问题:如果我们工程中的文件编码和IDE的默认编码不一致,也会导致windowbuilder的design界面无法正常显示。 3.插件问题:插件出现故障或版本冲突,会导致windowbuilder无法正常工作。 解决方法: 1.检查资源文件的配置:在创建工程时,一定要正确配置相关的资源文件,确保工程正常运行。 2.检查文件编码:在使用windowbuilder时,一定要确保工程的编码和IDE的默认编码相同,否则会影响界面的正常显示。 3.检查插件:如果windowbuilder无法正常工作,可能是插件故障或版本冲突所致。此时可以尝试卸载并重新安装插件,或者更新插件版本。 总之,无法显示windowbuilder的design界面通常都是由于资源文件的配置问题、文件编码问题或插件故障所导致的。我们只要注意这些方面,就可以避免这种问题的出现,并且更加愉快地进行Swing界面的设计工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值