大神带你玩转后端开发神器LomBok——一篇文章精通LomBok插件的原理和使用

文章目录

知识资源共享,一起交流怎么学习高效开发

请关注订阅,本专栏会详细讲解JAVA+高效开发
本篇内容专门为从事Java后端开发的面试者提供帮助,精准解决面试遇到的问题,欢迎讨论
在这里插入图片描述

什么是LomBok?

Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。
Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

如何引入Lombok依赖?

在pom文件中加入以下
<!--https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.16-->
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.16</version>
	<scope>provided</scope>
</dependency>
<!--scope=provided,说明它只在编译阶段生效,不需要打入包中, Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件-->
搜索Lombok插件,安装,按照图中所指挑对勾,之后重启idea

在这里插入图片描述

在这里插入图片描述

给单独bean的属性设置get/set方法

User对象声明(只给address字段设置get/set方法)
public class User {
    private Integer id;
    private String name;
    @Setter
    @Getter
    private String address;
    private Date date;
}
编译后生成的字节码文件
public class User {
    private Integer id;
    private String name;
    private String address;
    private Date date;

    public User() {
    }

    public void setAddress(final String address) {
        this.address = address;
    }

    public String getAddress() {
        return this.address;
    }
}

给整个类的字段加get/set方法

User对象声明
@Setter
@Getter
public class User {
    private Integer id;
    private String name;
    private String address;
    private Date date;
}
编译后生成的字节码文件
public class User {
    private Integer id;
    private String name;
    private String address;
    private Date date;

    public User() {
    }
    public void setId(final Integer id) {
        this.id = id;
    }
    public void setName(final String name) {
        this.name = name;
    }
    public void setAddress(final String address) {
        this.address = address;
    }
    public void setDate(final Date date) {
        this.date = date;
    }
    public Integer getId() {
        return this.id;
    }
    public String getName() {
        return this.name;
    }
    public String getAddress() {
        return this.address;
    }
    public Date getDate() {
        return this.date;
    }
}

指定get/set方法的访问级别

枚举类AccessLevel说明

NONE: Represents not generating anything or the complete lack of a method.
表示不生成任何东西或完全缺少方法。

在这里插入图片描述

User对象声明
@Setter(AccessLevel.PROTECTED)
@Getter
public class User {
    private Integer id;
    private String name;
    private String address;
    private Date date;
}
编译后生成的字节码文件(所有set方法的访问级别都是protected)
public class User {
    private Integer id;
    private String name;
    private String address;
    private Date date;

    public User() {
    }
    protected void setId(final Integer id) {
        this.id = id;
    }
    protected void setName(final String name) {
        this.name = name;
    }
    protected void setAddress(final String address) {
        this.address = address;
    }
    protected void setDate(final Date date) {
        this.date = date;
    }
    public Integer getId() {
        return this.id;
    }
    public String getName() {
        return this.name;
    }
    public String getAddress() {
        return this.address;
    }
    public Date getDate() {
        return this.date;
    }
}

不想生成某个字段的get/方法如何解决?

在类上方加注解@Setter/@Getter,在不想要get/set方法的字段上方加@Setter(AccessLevel.NONE)/@Getter(AccessLevel.NONE)

注意点:

  1. private final String name=“username”; 该语句不会给你生成set方法,因为被final修饰的字段只能被赋值一次.
  2. static Date createTime = new Date(); 该语句不会给你生成set/get方法,因为这是静态成员变量
  3. private static final String address = “中国”; 该语句不会给你生成set/get方法,因为这是静态成员变量

什么时候使用@NonNull注解

假设在User类中增加一个login()方法,如果name为空就抛出异常
    public void login(@NonNull String name){
        System.out.println("登录成功!");
    }
编译后字节码文件
public void login(@NonNull String name) {
        if (name == null) {
            throw new NullPointerException("name is marked non-null but is null");
        } else {
            System.out.println("登录成功!");
        }
    }

如何自动构建空构造函数、全参构造函数和部分参数构造函数

空构造函数:在类前加@NoArgsConstructor
全参构造函数:在类前加@AllArgsConstructor
选择部分参数构造函数 在类前加 @RequiredArgsConstructor ,在属性前加@NonNull

Lombok插件原理分析 并和反射技术做对比

JSR 269插件化注解处理:实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件。
JSR是Java Specification Requests的缩写,意思是Java 规范提案

  1. 首先进行Java源文件解析
  2. 然后根据AST语法树解析
  3. 然后进行注解处理(Annotation Processing),包括AST语法树修改
  4. 最后AST语法树修改完成,最后生成字节码文件。
    Javac 解析成AST抽象语法树后, Lombok根据自己编写的注解处理器,动态地修改 AST增加新的节点(即Lombok自定义注解所需要生成的代码),最终生成JVM可执行的字节码Class文件
反射技术是运行时动态修改,注解处理是编译时动态修改

Lombok如何使用toString()注解

在类上使用@ToString注解,自动 生成tostring方法
   public String toString() {
        return "User(id=" + this.getId() + ", name=" + this.getName() + ", address=" + this.getAddress() + ", date=" + this.getDate() + ")";
    }
如果不想要某个字段:@ToString(exclude = {“address”})
    public String toString() {
        return "User(id=" + this.getId() + ", name=" + this.getName() + ", date=" + this.getDate() + ")";
    }
如果想要包括哪些字段:@ToString(of = {“address”,“date”})
    public String toString() {
        return "User(address=" + this.getAddress() + ", date=" + this.getDate() + ")";
    }

如何使用@EqualsAndHashCode注解?(覆盖默认的hashcode和equals方法)

全部属性都做hash比较,就在类上加@EqualsAndHashCode注解
指定某些属性相等就相等,就用 @EqualsAndHashCode(of = {“id”,“name”})
不包括某个属性比较,就用 @EqualsAndHashCode(exclude = {“id”,“name”})

@Data注解的使用

@Data注解包括什么?
  1. @ToString
  2. @EqualsAndHashCode
  3. @Getter
  4. @Setter
  5. @RequiredArgsConstructor

@Builder建造者模式

在类前加上注解@Builder,在构造函数需要《不定个参数》的时候使用
使用方法
public static void main(String[] args) {
    User user = User.builder().address("中国").name("张三").build();
    System.out.println(user);
}
sout:
User(id=null, name=张三, address=中国, date=null)

日志注解@Slf4j怎么使用?

新建测试类
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Override
    public void login(String pwd, String phone) {
        log.debug("用户"+phone+"登录");
    }
}
编译后的字节码文件
@Service
public class UserServiceImpl implements UserService {
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
    public UserServiceImpl() {
    }
    public void login(String pwd, String phone) {
        log.debug("用户" + phone + "登录");
    }
}

Lombok的缺点

  1. 别人要用有Lombok的项目必须也得安装插件,不然会报错
  2. 可读性差
  3. 比如只使用了@Data,而不使用@EqualsAndHashCode(callSuper=true)的话,会默认是@EqualsAndHashCode(callSuper=false),这时候生成的equals()方法只会比较子类的属性,不会考虑从父类继承的属性,无论父类属性访问权限是否开放,只要知道是否需要使用父类的属性即可,也提供定制化配置,所以不用过多担心

Lombok的优点

  1. 使用注解,简洁明了,提高效率
  2. 代码量减少
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java天下第1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值