2024-01-10  阅读(13)
原文作者:猫巳 原文地址: https://moonce.blog.csdn.net/article/details/121793718

一、简介

这组3个注释生成一个构造函数,该构造函数将为某些字段接受1个参数,并将该参数简单地分配给该字段。

@NoArgsConstructor将生成一个没有参数的构造函数。如果这是不可能的(因为有final字段),将产生一个编译器错误,除非使用@NoArgsConstructor(force = true),那么所有最终字段将被初始化为0 / false / null。对于有约束条件的字段,如@NonNull字段,不会产生检查,所以要注意这些约束条件一般不会被满足,直到这些字段在以后被正确初始化。某些java构造,如hibernate和服务提供者接口,需要一个无args构造函数。这个注解主要是与@Data或其他构造函数生成注解结合使用。

@RequiredArgsConstructor为每个需要特殊处理的字段生成一个具有1个参数的构造函数。所有未初始化的final字段都会获得一个参数,以及任何标记为@NonNull且未在声明位置初始化的字段。对于标记为@NonNull的字段,还将生成显式null检查。如果用于标记为@NonNull的字段的任何参数包含null,则构造函数将抛出NullPointerException。参数的顺序与字段在类中的显示顺序相匹配。

@AllArgsConstructor为你的类中的每个字段生成一个带有1个参数的构造函数。标有@NonNull的字段会导致对这些参数的空值检查。

这些注解中的每一个都允许另一种形式,即生成的构造函数始终是私有的,并生成一个额外的静态工厂方法,该方法围绕私有构造函数。这种模式是通过为注解提供staticName值来启用的,像这样。@RequiredArgsConstructor(staticName="of")。这样的静态工厂方法将推断出泛型,与普通构造函数不同。这意味着你的API用户会得到写MapEntry.of("foo", 5)而不是更长的new MapEntry<String, Integer>("foo", 5)

要在生成的构造函数上加上注释,你可以使用onConstructor=@__({@AnnotationsHere}),但要小心,这是一个实验性的功能。更多细节请参见关于onX功能的文档。

与大多数其他lombok注释不同,显式构造函数的存在并不会阻止这些注释生成自己的构造函数。这意味着您可以编写自己的专用构造函数,并让lombok生成样板。如果出现冲突(其中一个构造函数的签名与lombok生成的签名相同),则会发生编译器错误。

二、示例比较

1. Lombok 写法

    import lombok.AccessLevel;
    import lombok.RequiredArgsConstructor;
    import lombok.AllArgsConstructor;
    import lombok.NonNull;
    
    @RequiredArgsConstructor(staticName = "of")
    @AllArgsConstructor(access = AccessLevel.PROTECTED)
    public class ConstructorExample<T> {
      private int x, y;
      @NonNull private T description;
      
      @NoArgsConstructor
      public static class NoArgsExample {
        @NonNull private String field;
      }
复制代码

2. Java 标准写法

    public class ConstructorExample<T> {
      private int x, y;
      @NonNull private T description;
      
      private ConstructorExample(T description) {
        if (description == null) throw new NullPointerException("description");
        this.description = description;
      }
      
      public static <T> ConstructorExample<T> of(T description) {
        return new ConstructorExample<T>(description);
      }
      
      @java.beans.ConstructorProperties({"x", "y", "description"})
      protected ConstructorExample(int x, int y, T description) {
        if (description == null) throw new NullPointerException("description");
        this.x = x;
        this.y = y;
        this.description = description;
      }
      
      public static class NoArgsExample {
        @NonNull private String field;
        
        public NoArgsExample() {
        }
      }
    }
复制代码

三、支持的配置项

lombok.anyConstructor.addConstructorProperties = [true | false] (默认: false)
如果设置为true,那么lombok将为生成的构造函数添加@java.beans.ConstructorProperties

lombok.[allArgsConstructor|requiredArgsConstructor|noArgsConstructor].flagUsage = [warning | error] (默认: not set)
Lombok会将相关注释(@AllArgsConstructor@RequiredArgsConstructor@NoArgsConstructor)的任何使用标记为警告或错误(如果已配置)。

lombok.anyConstructor.flagUsage = [warning | error] (默认: not set)
Lombok会将生成注释的3个构造函数中的任何一个的使用标记为警告或错误(如果已配置)。

lombok.copyableAnnotations = [完全限定类型的列表] (默认: empty list)
Lombok会将这些注释从字段复制到构造函数参数、setter参数和getter方法。请注意,lombok附带了一系列可复制的“开箱即用”注释:所有流行的nullable/nonnull注释。

lombok.noArgsConstructor.extraPrivate = [true | false] (默认: false)
如果为truelombok将为任何@Value@Data注释类生成一个私有的无参数构造函数,该构造函数将所有字段设置为默认值(null/0/false)。

四、附属说明

即使一个字段被明确地初始化为nulllombok也会认为避免null的要求得到了满足,并且不会将该字段视为一个 "required"的参数。我们的假设是,如果你明确地将null赋值给一个你已经标记为@NonNull的字段,你一定知道你在做什么。

对于没有参数的构造函数,永远不会生成@java.beans.ConstructorProperties注释。这也解释了@NoArgsConstructor缺少suppressConstructorProperties注释方法的原因。生成的静态工厂方法也不能获取@ConstructorProperty,因为此注释只能添加到实际构造函数中。

@XArgsConstructor也可以用在枚举定义上。生成的构造函数将总是私有的,因为非私有的构造函数在枚举中是不合法的。你不需要指定AccessLevel.PRIVATE

关于空性的各种众所周知的注释会导致插入空检查并将其复制到参数。有关更多信息,请参阅Getter/Setter文档的附属说明。

当构造函数由@Data@Value或任何其他lombok注解生成时,flagUsage配置键不会触发。

参考文献

【1】@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文