当前位置: 代码网 > it编程>编程语言>Java > Java中@RequiredArgsConstructor注解的基本用法

Java中@RequiredArgsConstructor注解的基本用法

2024年09月04日 Java 我要评论
前言从源码中学习,事因是看到项目代码中有所引用@requiredargsconstructor 是 lombok 提供的一个注解,用于自动生成一个包含所有 final 字段和带有 @nonnull 注

前言

从源码中学习,事因是看到项目代码中有所引用

@requiredargsconstructor 是 lombok 提供的一个注解,用于自动生成一个包含所有 final 字段和带有 @nonnull 注解字段的构造函数

这可以减少样板代码,尤其是在需要依赖注入时

1. 基本知识

lombok 是一个 java 库,通过注解简化代码

常用注解包括 @getter, @setter, @tostring, @equalsandhashcode, 和 @data 等

针对@requiredargsconstructor 注解会生成一个包含所有 final 字段和带有 @nonnull 注解字段的构造函数 

这对于构造必须初始化这些字段的对象非常有用

基本的语法如下:

@requiredargsconstructor
public class myclass {
    private final string name;
    private final int age;
    private string address;
    
    @nonnull
    private string phonenumber;
}

对应生成的构造函数如下:

public myclass(string name, int age, string phonenumber) {
    this.name = name;
    this.age = age;
    this.phonenumber = phonenumber;
}

对应需要注意的事项如下:

  • 字段的顺序:生成的构造函数中的参数顺序是按照字段在类中定义的顺序
  • @nonnull 注解:如果某个字段带有 @nonnull 注解,它也会包含在构造函数中,即使它不是 final 的。

与其他构造函数冲突:如果手动定义了构造函数,@requiredargsconstructor 生成的构造函数可能会与其冲突

与其他注解比较:

  • @noargsconstructor:生成一个无参构造函数。
  • @allargsconstructor:生成一个包含所有字段(包括非 final 字段)的构造函数

2. 源码解读

先看源码的对应属性

对应的属性分析如下:

staticname:

  • 设置了这个属性,会生成一个静态方法,该方法调用私有构造函数
  • 这个静态方法主要用于推断类型参数

onconstructor:

  • 允许在生成的构造函数上添加指定的注解
  • jdk 7 和 jdk 8 的语法稍有不同。

access:

  • 设置构造函数的访问级别
  • 默认是 public,可以设置为 private, protected 或 package

针对源码结合以下demo进行展示

3. demo

3.1 简易demo

import lombok.nonnull;
import lombok.requiredargsconstructor;

@requiredargsconstructor
public class test {
    private final string firstname;
    private final string lastname;
    @nonnull
    private string email;
    private int age;

    public static void main(string[] args) {
        // 正确使用示例
        test person = new test("码农", "研究僧", "https://blog.csdn.net/weixin_47872288");
        system.out.println("person created: " + person);

        // 错误使用示例(会导致编译错误)
        // person person2 = new person("jane", "doe");
    }

    @override
    public string tostring() {
        return "person{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

明确需要3个属性,不可超过4个

再者对应的字段属性是按照顺序的,如果更换顺序会出现如下场景:

test person = new test("码农","https://blog.csdn.net/weixin_47872288","研究僧");

3.2 staticname属性

@requiredargsconstructor(staticname = "of") 

会生成一个静态方法 of 来实例化对象,而不是直接调用构造函数

import lombok.allargsconstructor;
import lombok.nonnull;
import lombok.requiredargsconstructor;

@requiredargsconstructor(staticname = "of")
public class test {
    private final string firstname;

    private final string lastname;
    private final string email;

    public static void main(string[] args) {
        test example = test.of("码农","研究僧","https://blog.csdn.net/weixin_47872288");
        system.out.println(example);
    }

    @override
    public string tostring() {
        return "staticconstructorexample{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

截图如下:

3.3 onconstructor属性

@requiredargsconstructor(onconstructor_ = @__(@customannotation("custom constructor"))) 

会在生成的构造函数上添加 @customannotation

import lombok.allargsconstructor;
import lombok.nonnull;
import lombok.requiredargsconstructor;

import java.lang.annotation.elementtype;
import java.lang.annotation.retention;
import java.lang.annotation.retentionpolicy;
import java.lang.annotation.target;

@target({elementtype.constructor})
@retention(retentionpolicy.runtime)
@interface customannotation {
    string value();
}
@requiredargsconstructor(onconstructor_ = @__(@customannotation("custom constructor")))
public class test {
    private final string firstname;

    private final string lastname;
    private final string email;

    public static void main(string[] args) {
        test example = new test("码农","研究僧","https://blog.csdn.net/weixin_47872288");
        system.out.println(example);
    }

    @override
    public string tostring() {
        return "staticconstructorexample{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

3.4 access属性

@requiredargsconstructor(access = accesslevel.private, staticname = "of")
public class test {
    private final string firstname;

    private final string lastname;
    private final string email;

    public static void main(string[] args) {
        test example = test.of("码农", "研究僧", "https://blog.csdn.net/weixin_47872288");
        system.out.println(example);
    }

    @override
    public string tostring() {
        return "staticconstructorexample{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

不需要构造函数是私有的,可以将构造函数的访问级别设置为 public 或 protected,直接进行new

但是我的private它竟然可以new(神奇=-=)

4. @allargsconstructor比较

使用 @requiredargsconstructor 时,只有 final 字段和 @nonnull 字段会被初始化

但是@allargsconstructor 生成一个构造函数,该构造函数包含类中所有字段,无论它们是否为 final 或带有 @nonnull 注解

@allargsconstructor
public class test {
    private final string firstname;
    private  string lastname;
    @nonnull
    private string email;
    private int age;

    public static void main(string[] args) {
        // 正确使用示例
        test person = new test("码农","研究僧","https://blog.csdn.net/weixin_47872288",18);
        system.out.println("person created: " + person);

        // 错误使用示例(会导致编译错误)
        // person person2 = new person("jane", "doe");
    }

    @override
    public string tostring() {
        return "person{" +
                "firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

截图如下:(必须要有四个参数)

这两者都可以实用构造函数注入,但推荐使用@requiredargsconstructor,因为它只会初始化那些在创建对象时必需的字段

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com