Lombok的使用
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;//是否推荐
}