Lombock完整教学(使用&原理)

Lombock

第一章 介绍

什么是Lombock

  • 一个优秀的Java代码库,简化了Java的编码,为Java代码的精简提供了一种方式
  • 你是否发现每个JavaBean都会写getter,setter,equals,hashCode和toString的模板代码,特别的多于没技术
  • lombok消除Java的冗长代码,尤其是对于简单的Java对象,只要加上注解就行

使用方式

  • 添加依赖

    • scope=provided,说明它只在编译阶段生效,不需要打入包中, Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.16</version>
        <scope>provided</scope>
    </dependency>
    
  • 添加IDE工具对Lombok的支持

    • 点击File-- Settings设置界面,安装Lombok插件,然后重启idea

第二章 Setter/Getter

2.1 基本介绍

常见注解@Getter/@Setter

  • 作用类上,生成所有成员变量的getter/setter方法
  • 作用于成员变量上,生成该成员变量的getter/setter方法

进一步控制

  • 方法控制访问级别 set和get注解加上
    • @Getter(AccessLevel.PROTECTED)
  • 不生成set、get方法
    • @Getter(AccessLevel.NONE)

2.2 代码案例

@Setter
@Getter
public class User {
    /**
     * 不想生成 get方法
     */
    @Getter(AccessLevel.NONE)
    private int age;
    
    /**
     * 控制访问权限
     */
    @Getter(AccessLevel.PROTECTED)
    private int salary;
    
    /**
     * final 只会生成get
     */
    private final String name="柠檬啦灬";
    
    /**
     * 下面两个静态成员变量不会生成set/get方法
     */
    static Date createTime = new Date();
    private static final String address = "M78";
}

2.3 字节码 mvn compile

public class User {
    private int age;
    private int salary;
    private final String name = "柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";

    public User() {
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public String getName() {
        this.getClass();
        return "柠檬啦灬";
    }

    protected int getSalary() {
        return this.salary;
    }
}

第三章 NonNull

3.1 基本介绍

@NonNull

  • 作用于方法上或者属性,用于非空判断,如果为空则抛异常

3.2 代码案例

public void test(@NonNull  String email){
       this.email = email;
}

3.3 字节码

public void test(@NonNull String email) {
    if (email == null) {
        throw new NullPointerException("email is marked non-null but is null");
    } else {
        this.email = email;
    }
}

第四章 构造函数注解ArgsConstructor

4.1 基本介绍

@NoArgsConstructor

  • 生成无参构造器

@AllArgsConstructor

  • 生成全参构造器

@RequiredArgsConstructor

  • 指定参数的构造函数,有以下的特征的字段
    • final类型未被初始化的属性, 标记了@NonNull的属性
    • 注意:@NoArgsConstructor不能加

4.2 代码案例

@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int age;
    private int salary;
    private final String name="柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";
}
@AllArgsConstructor
@RequiredArgsConstructor
public class User {
    private int age;
    private int salary;
    private final String name="柠檬啦灬";
    @NonNull
    private final String nickname;
    static Date createTime = new Date();
    private static final String address = "M78";
}

4.3 字节码

public class User {
    private int age;
    private int salary;
    private final String name = "柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";

    public User() {
    }

    public User(int age, int salary) {
        this.age = age;
        this.salary = salary;
    }
}
public class User {
    private int age;
    private int salary;
    private final String name = "柠檬啦灬";
    @NonNull
    private final String nickname;
    static Date createTime = new Date();
    private static final String address = "M78";
    public User(int age, int salary, @NonNull String nickname) {
        if (nickname == null) {
            throw new NullPointerException("nickname is marked non-null but is null");
        } else {
            this.age = age;
            this.salary = salary;
            this.nickname = nickname;
        }
    }
    public User(@NonNull String nickname) {
        if (nickname == null) {
            throw new NullPointerException("nickname is marked non-null but is null");
        } else {
            this.nickname = nickname;
        }
    }
}

第五章 toString()注解

5.1 基本介绍

java bean对象为啥要重写toString方法?

  • List或者其他集合调试不方便
  • 控制台或者日志输出对象,默认打印的是内存地址

@ToString

  • 作用于类,覆盖默认的toString()方法

不包括某个字段:@ToString(exclude = {"age"})

只输出某个字段:@ToString(of = {"name"})

5.2 代码案例

@ToString
public class User {
    private int age;
    private int salary;
    private final String name="柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";
}

5.3 字节码

public class User {
    private int age;
    private int salary;
    private final String name = "柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";

    public User() {
    }

    public String toString() {
        StringBuilder var10000 = (new StringBuilder()).append("User(age=").append(this.age).append(", salary=").append(this.salary).append(", name=");
        this.getClass();
        return var10000.append("柠檬啦灬").append(")").toString();
    }
}

第六章 EqualsAndHashCode

6.1 基本介绍

@EqualsAndHashCode

  • 作用于类,覆盖默认的equals和hashCode, 作用于全部属性

不包括某个属性:@EqualsAndHashCode(exclude = {"age"})

只输出某个属性:@EqualsAndHashCode(of = {"name"})

6.2 代码案例

@EqualsAndHashCode
public class User {
    private int age;
    private int salary;
    private final String name="柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";
}

6.3 字节码

public class User {
    private int age;
    private int salary;
    private final String name = "柠檬啦灬";
    static Date createTime = new Date();
    private static final String address = "M78";

    public User() {
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof User)) {
            return false;
        } else {
            User other = (User)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (this.age != other.age) {
                return false;
            } else if (this.salary != other.salary) {
                return false;
            } else {
                this.getClass();
                Object this$name = "柠檬啦灬";
                other.getClass();
                Object other$name = "柠檬啦灬";
                if (this$name == null) {
                    if (other$name == null) {
                        return true;
                    }
                } else if (this$name.equals(other$name)) {
                    return true;
                }

                return false;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof User;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        int result = result * 59 + this.age;
        result = result * 59 + this.salary;
        this.getClass();
        Object $name = "柠檬啦灬";
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        return result;
    }
}

第七章 Data

7.1 基本介绍

Lombok前面讲了多个注解,一个个加也麻烦吧

@Data, 定义一个干净的类,增加此注解,mvn compile查看字节码

作用于类上,是以下注解的集合

  • @ToString
  • @EqualsAndHashCode
  • @Getter
  • @Setter
  • @RequiredArgsConstructor

7.2 元注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
    String staticConstructor() default "";
}

第八章 建造者模式Builder

帮你生成了set、get方法,还在苦苦的一个个赋值????

构造者模式:又称之为建造者模式

  • 场景:当一个bean类重载了多个构造方法时,并且参数随机使用时,考虑使用构造者模式
  • 谷歌的开源的protobuf协议生产的java bean赋值就是采用建造者模式

@Builder注解

  • 作用在类上
//添加
@Builder
@Data
public class StudentDO {
}

//使用
StudentDO studentDO = StudentDO.builder().age(1).email("396451989@qq").build();
System.out.println(studentDO);

第九章 Log日志输出打印@Log-@Slf4j

9.1 基本介绍

@Log / @Slf4j

  • 作用于类上,生成日志变量, 用于记录日志

如果不生效,记得检查下面的配置,另外重新更新下lombok插件,重启idea

  • 开始按照创建的那边,记得开启 开启annotion processing

9.2 代码案例

@Log
public class Student {
    public void test(String email){
        log.info("有偿解决异常加Q396451989");
        this.email = email;
    }
}

9.3 字节码

public class Student {
    private static final Logger log = Logger.getLogger(StudentDO.class.getName());
}

第十章 Lombok插件原理-对比反射技术

光会用就行了?肯定是不行的啊,知其所以然才行的,实现这样神器的效果是咋做的

熟悉Java自定义注解的同学已经猜到是:JSR 269插件化注解处理

  • JSR 269: Pluggable Annotation Processing API
  • 实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件
  • 官网

科普

  • JSR是Java Specification Requests的缩写,意思是Java 规范提案。
  • 是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。
  • 任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

Lombok解析流程如下

在这里插入图片描述

Javac 解析成AST抽象语法树后, Lombok根据自己编写的注解处理器,动态地修改 AST增加新的节点(即Lombok自定义注解所需要生成的代码),最终生成JVM可执行的字节码Class文件

可以看编译后的在target目录下的class文件

能实现上述效果的还有一个反射技术,那两个对比如何?

  • 使用Annotation Processing自定义注解是在编译阶段进行修改
  • JDK的反射技术是在运行时动态修改
  • 结论:反射更加灵活一些但是带来的性能损耗更加大

第十一章 Lombok优点和缺点

缺点:

  • Lombok的使用要求一定要在IDE中安装对应的插件,如果项目组中有一个人使用了Lombok则都要用
  • 代码可读性,可调试性低,比如想知道某个类中的某个属性的getter方法都被哪些类引用
  • 影响升级,如果升级到某个新版本的JDK的时候,如果其中的特性在Lombok中不支持的话就会受到影响

注意常见的细节点

  • 比如只使用了@Data,而不使用@EqualsAndHashCode(callSuper=true)的话,会默认是@EqualsAndHashCode(callSuper=false),这时候生成的equals()方法只会比较子类的属性,不会考虑从父类继承的属性,无论父类属性访问权限是否开放,只要知道是否需要使用父类的属性即可,也提供定制化配置,所以不用过多担心

  • 优点:

    • 使用注解即可帮忙自动生成代码
    • 大大减少了代码量,使代码非常简洁
    • 部分注解在业务项目中开发能大大提高效率
  • 项目中应该用还是不用呢

    • 不建议开发中间件的项目使用,中间件设计的要求是解耦少依赖
    • 业务项目实体类可以用,且用的时候知道对应的常见的注解原理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值