Lombok学习使用笔记1
Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能(百度), 在日常写代码的过程中还是经常有使用到的,一定程度上提高了写代码的效率。是在看完b站up 御风大世界的 Lombok还能这么玩?代码效率翻倍,爱不释手-哔哩哔哩,此博客就是在此基础上加个个人理解所写的笔记 比较详细 供以后复习查看
笔记主要以代码方式呈现,相关笔记都记录在注释中, 可以直接复制后在本地运行
写在之前,使用 Lombok 的前提工作很简单,以 Maven 项目为例,只需要导入 Lombok 坐标, 再下载 Lombok 插件就可以了,使用 IDEA 的话会有相应的提示
日志以及基本的(Getter Setter ToString EqualsAndHashCode)
import lombok.*;
import lombok.extern.slf4j.Slf4j;
/**
* @Slf4j
* @XSlf4j
* @Log
* @Log4j
* @Log4j2
* @CommonsLog
* @JBossLog
* @Getter
* @Setter
* @EqualsAndHashCode
* @ToString
*/
@Slf4j //打印日志以下这么几种,选一个使用 常用 @Slf4j
//@XSlf4j
//@Log
//@Log4j
//@Log4j2
//@CommonsLog
//@JBossLog
public class LombokDemo_1 {
/**
* 基本 getter setter toString equalsAndHashCode 简明知意
* 简化代码,提高写代码效率
*/
@Getter//生成属性 getter 方法
@Setter//生成属性 setter 方法
@EqualsAndHashCode(of = {"name","sex"})//重写类 equals 和 hashCode 方法, 可以通过注解的 of 属性指定哪些字段参与
@ToString(of = {"name","salary"})// 重写类 toString 方法,可以通过注解的 of 属性指定哪些字段参与
private static class Test_01{
private String name;
private Integer age;
private Float salary;
private Byte sex;
}
public static void main(String[] args) {
/**测试 Test_01 */
Test_01 test_01 = new Test_01();
// setter
test_01.setAge(1);
test_01.setName("tom");
test_01.setSalary(3333.3F);
test_01.setSex((byte) 1);
// getter
System.out.println(test_01.getAge());
System.out.println(test_01.getName());
System.out.println(test_01.getSalary());
System.out.println(test_01.getSex()==1?"男":"女");
// toString
System.out.println(test_01);
// equals hashCode
// 创建一个新的Test_01对象
Test_01 test_011 = new Test_01();
test_011.setName("tom");
test_011.setSex((byte) 1);
test_011.setAge(111);
// 测试
System.out.println(test_01 == test_011);//F "==" 比较的是地址,作为两个通过 new 出来的对象实例,一定是 false
System.out.println(test_01.equals(test_011));// T 重写了 equals 方法,且参与的字段仅有 name 和 sex 所以为 true
System.out.println(test_01.hashCode() == test_011.hashCode());//T 理由同上
}
}
全参构造器 @AllArgsConstructor
空构造器 @NoArgsConstructor
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
/**
* @AllArgsConstructor
* @NoArgsConstructor
*/
public class LombokDemo_2 {
@AllArgsConstructor //全参构造函数
@NoArgsConstructor(access = AccessLevel.PRIVATE)// 无参构造函数 这里 access 是指定该无参构造函数的访问权限
// 例如这里设置的就是 private --> 可以应用到单例
private static class Test_02{
private String name;
private Integer age;
}
public static void main(String[] args) {
/** 测试 Test_02 */
// NoArgs
// 访问权限为 private 照理来说除了 Test_02 自己,是不能调用其无参构造函数的
// 但是此处 Test_02 作为 LombokDemo_2 的一个内部类,等同于是 LombokDemo_2 的一个属性, 根据类内可见原则可知,此处是可以调用的
Test_02 test_02 = new Test_02();
// AllArgs
// 是有字段顺序的请注意,若顺序出错会报错(编译阶段检错)
new Test_02("tom",21);
// new Test_02(21,"tom"); // 参数顺序有误
}
}
@Data
@Value
import lombok.Data;
import lombok.Value;
/**
* @Data
* @Value
*/
public class LombokDemo_3 {
@Data //复合注解,用在类上,使用后会生成:默认的无参构造函数、所有属性的 getter、所有非 final 属性的 setter 方法,并重写 toString、equals、hashcode 方法
private static class Test_03_1{
private String name;
private Integer age;
}
@Value //@Value 注解和 @Data 类似,区别在于它会把所有成员变量默认定义为 private final 修饰,并且不会生成 set() 方法 (private final 就意味着不可修改,不提供 setter 方法是合理的)
private static class Test_03_2{
private String name;
private Integer age;
}
public static void main(String[] args) {
/**测试 LombokDemo_2.Test_02 的无参构造方法*/
// new LombokDemo_2().Test_02();
/** 测试 Test_03_1 */
// Test_03_1 xh = new Test_03_1("小红", 123); // @Data 不包含全参构造方法
Test_03_1 test_03_1 = new Test_03_1();
test_03_1.setAge(12);// @Data 包含 setter 方法
test_03_1.getAge();
/** 测试 Test_03_2 */
Test_03_2 xhh = new Test_03_2("小黄", 123);
// Test_03_2 test_03_2 = new Test_03_2();// @Value 不包含无参构造方法
// test_03_2.setAge(12); // @Value 不包含 setter 方法
// test_03_2.getAge();
}
}
@Builder
@Singular
import lombok.Builder;
import lombok.Singular;
import lombok.ToString;
import java.util.List;
/**
* @Builder
* @Singular
*/
public class LombokDemo_4 {
/**
@Builder 将类变成建造者模式,使其可以以链的形式调用 (链式编程)
值得注意的是, 此时 例如 name age 属性字段都会在 builder 链路中变成同名的 setter 方法 name() age()
*/
@Builder
@ToString // 方便打印检验结果
private static class Test_04{
private String name;
private Integer age;
@Singular("addHobby") // 作为配合 @Builder 使用的注解, 通俗的讲就是在待添加的集合属性生成器中创建单个元素的添加方法(此处是addHobby())-> 源码解释
private List<String> hobby;
}
public static void main(String[] args) {
/** 测试 Test_04 */
System.out.println(Test_04.builder().name("小明").age(18).addHobby("music").addHobby("ball").build());
// LombokDemo_4.Test_04(name=小明, age=18, hobby=[music, ball])
}
}
@SneakyThrows
@Synchronized
@Cleanup
import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.Synchronized;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @SneakyThrows
* @Synchronized
* @Cleanup
*/
public class LombokDemo_5 {
private static class Test_05 {
@SneakyThrows // 相当于使用 try{}catch(){} 代码块包装内部有可能出现异常的地方
public void somethingHappen() {
Thread.sleep(1000L);
}
@Synchronized // public void testSynchronized() -> public synchronized void testSynchronized()
public void testSynchronized() {
}
public void copyFile(String in, String out) throws IOException {
// @Cleanup 相当于我们使用 finally 代码块来关闭资源,起到自动关闭资源的作用,简化代码,还是比较好用 也常用
@Cleanup FileInputStream fileInputStream = new FileInputStream(in);
@Cleanup FileOutputStream fileOutputStream = new FileOutputStream(out);
byte[] buffer = new byte[65536];
while (true) {
int read = fileInputStream.read(buffer);
if (read == -1) {
break;
}
fileOutputStream.write(buffer,0,read);
}
}
}
}
val
@Accessors(fluent = true)
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.val;
/**
* val
* var
* @Accessors (fluent = true) default:false
*/
public class LombokDemo_6 {
@Data
@Accessors(fluent = true)// 将getter setter 合并重载到同字段名的方法上
private static class Test_06{
private String name;
private Integer age;
}
public static void main(String[] args) {
/** 测试 Test_06*/
Test_06 test_06 = new Test_06();
Test_06 age1 = test_06.age(17);// setter 返回值是对象实例
Integer age = test_06.age();// getter 返回值是响应字段
// 有点花哨,感觉有点不太适合强类型的 java (个人认为)
var name = test_06.name();
val ageTest = test_06.age();
}
}
@Accessors (chain = true)
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Accessors (chain = true)
*/
public class LombokDemo_7 {
@Data
@Accessors(chain = true) // 本质是将 setter 方法的返回值由 void 改为对应类实例
private static class Test_07{
private String name;
private Integer age;
}
public static void main(String[] args) {
Test_07 test_07 = new Test_07();
// 由于类挂上了 @Accessors(chain = true) 注解,所以此处代码可以像链式编程一样写,很方便,应用场景也挺多的
// 有点类似于 @Builder
test_07.setAge(8).setName("hh");
}
}
~~ 未完待续