Lombok的使用

Lou.Chen
大约 6 分钟

1、Lombok

使用

引入lombok依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.20</version>
    <scope>provided</scope>
</dependency>
① @Data

​ 注解在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString,无参构造器。如为final属性,则不会为该属性生成setter方法。

自定义其他方法则会覆盖其生成的方法

@Data  
public class Label implements Serializable {
    // 主键
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}
生成的canEqual()方法
protected boolean canEqual(Object other) {
    return other instanceof Label;
  }
instanceof 用法:
instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false
生成的equals()方法
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Label label = (Label) o;
        return id.equals(label.id) &&
                labelname.equals(label.labelname) &&
                state.equals(label.state) &&
                count.equals(label.count) &&
                fans.equals(label.fans) &&
                recommend.equals(label.recommend);
}
生成的hashcode()方法
@Override
public int hashCode() {
      //返回31+每个属性的hasecode()地址   若都为空则返回0
      return Objects.hash(id, labelname, state, count, fans, recommend);
}
② @Getter/@Setter

在类上@Getter/@Setter: 为所有属性生成get/set方法

@Getter@Setter
public class Label implements Serializable {
    // 主键
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}

在属性上@Getter/@Setter :为指定属性生成get/set方法

public class Label implements Serializable {
    // 主键
    @Getter@Setter
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}
③ @NonNull

该注解用在属性或构造器上,Lombok会生成一个非空的声明,可用于校验参数,能帮助避免空指针。

public class Label implements Serializable {
    // 主键
    @NonNull
    @Getter@Setter
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
    
    public Label(@NonNull String id) {
        this.id = id;
    }
}

实现方式:

public Label(@NonNull String id) {
    if (id == null) {
      throw new NullPointerException("id");
    }
    this.id = id;
}
④ @Cleanup

该注解能帮助我们自动调用close()方法,很大的简化了代码。

import lombok.Cleanup;
import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
  }
}
⑤ @EqualsAndHashCode

用在类上,自动生成equals方法和hashCode,canEqual方法

默认情况下,会使用所有非静态(non-static)和非瞬态(non-transient)属性来生成equals和hasCode,canEqual也能通过exclude注解来排除一些属性。

@EqualsAndHashCode(exclude = "id")
public class Label implements Serializable {
    // 主键
    @Id
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}
transient用法:
①:一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
②:transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
③:被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化
⑥ @ToString

​ 类使用@ToString注解,Lombok会生成一个toString()方法,默认情况下,会输出类名、所有属性(会按照属性定义顺序),用逗号来分割。通过exclude排除一些属性

@EqualsAndHashCode(exclude = "id")
@Getter
@Setter
@ToString(exclude = "id")
public class Label implements Serializable {
    // 主键
    @Id
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐

}
⑦ .1 @NoArgsConstructor

无参构造器、部分参数构造器、全参构造器。Lombok没法实现多种参数构造器的重载。

@NoArgsConstructor生成一个无参构造方法。当类中有final字段没有被初始化时,编译器会报错,此时可用@NoArgsConstructor(force = true),然后就会为没有初始化的final字段设置默认值 0 / false / null。对于具有约束的字段(例如@NonNull字段),不会生成检查或分配,因此请注意,正确初始化这些字段之前,这些约束无效。

@EqualsAndHashCode
@Getter
@Setter
@ToString
@NoArgsConstructor(force = true)
public class Label implements Serializable {
    // 主键
    @Id
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}
⑦.2 @RequiredArgsConstructor

@RequiredArgsConstructor会生成构造方法(可能带参数也可能不带参数),如果带参数,这参数只能是以final修饰的未经初始化的字段,或者是以@NonNull注解的未经初始化的字段

@RequiredArgsConstructor
public class Label implements Serializable {
    // 主键
    @Id
    @NonNull
    private String id;//
    @NonNull
    private String labelname;//标签名称
    private String state;//状态
    @NonNull
    private Long count;//使用数量
    private final Long fans;//关注数
    private String recommend;//是否推荐
}
final用法:

修饰成员变量已赋值时,不能被修改

修饰成员变量没有被赋值,依据不同对象值有所不同。

final参数 当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。 注:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。 final不能用于修饰构造方法。

1、final类不能被继承

2、final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。 使用final方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

3、 final变量(常量) 用final修饰的成员变量表示常量,只能被赋值一次,赋值后值无法改变! final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。 从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。 另外,final变量定义的时候,可以先声明,而不给初值,这种变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

@RequiredArgsConstructor(staticName = "of")会生成一个of()的静态方法,并把构造方法设置为私有的

通过 Lable.of(); 创建定义的有参对象

@EqualsAndHashCode
@Getter
@Setter
@ToString
@NoArgsConstructor
@RequiredArgsConstructor(staticName = "of")
public class Label implements Serializable {
    // 主键
    @Id
    @NonNull
    private String id;//
    @NonNull
    private String labelname;//标签名称
    private String state;//状态
    @NonNull
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}
⑦. @AllArgsConstructor

@AllArgsConstructor 生成一个全参数的构造方法,默认不提供无参构造。

@AllArgsConstructor
public class Label implements Serializable {
    // 主键
    private String id;//
    private String labelname;//标签名称
    private String state;//状态
    private Long count;//使用数量
    private Long fans;//关注数
    private String recommend;//是否推荐
}