欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Lombok 简洁你的代码

程序员文章站 2022-04-08 22:48:27
...

使用Lombok 简洁你的代码


【官方介绍】

Lombok 项目是一个Java库,它会自动插入您的编辑器和构建工具中,从而为您的Java增光添彩. 永远不要再写另一个getter或equals方法,带有一个注释的您的类有一个功能全面的生成器,自动化您的日志记录变量等等。

简单来说,就是消除Java中的冗长代码,对于简单的Java对象,通过注解来实现。

俺其实只记得一个课代表注解(其他的能不知道,这个可得记好了),其他的也不太清楚。现在总结一下常用注解,在日后的代码中减少冗余


Lombok原理

JSR 269:插件话处理API

Java中的注解如果我们按运行机制分,可以分为:

  • 源码注解,只在源码中存在
  • 编译时注解,在class中依然存在,如@Deprecated
  • 运行时注解,运行阶段起作用,如@Autowired

使用Lombok 简洁你的代码
Lombok的注解其实是编译时注解,它在编译期间通过注解的方式把我们需要的如get()、set()方法生成到 .class 文件中

在实体类中,你本身并没有写get()、set()方法,但是在虚拟机运行时它其实是存在的,你只是通过注解,让Lombok帮你写了

在阅读代码时,我们看到的只是几个简单的@Annotation,编译时lombok帮你生成,达到消除冗长代码的作用

Lombok常用注解表

使用Lombok 简洁你的代码
注解表

注解名 作用
@Setter 生成setter方法
@Getter 生成getter方法
@NoArgsConstructor 生成空参构造
@AllArgsConstructor 生成全部参数构造
@RequiredArgsConstructor 将标记为@NoNull的属性生成一个构造器
@ToString 生成所有属性的toString()方法
@EqualsAndHashCode 生成equals()方法和hashCode方法
@Data @Data直接修饰POJO or beans, getter所有的变量,setter所有不为final的变量。默认生成的所有的Annotation都是public的,如果需要不同权限修饰符可以使用AccessLevel.NONE选项
@Builder 构造Builder模式的结构,通过内部类Builder()进行构建对象
@Synchronized 同步方法
@Cleanup 自动调用close方法关闭资源
@SneakyThrows 可以对受检异常进行捕捉并抛出

Lombok常用注解

Getter & Setter

  • 所有成员变量添加GetterSetter,在类外定义
@Getter
@Setter
public class User {
    private int id;
    private int age;
    private String username;
    private String password;
}
  • 权限修饰
@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PRIVATE)
public class User {
    private int id;
    private int age;
    private String username;
    private String password;
}
  • 只生成某一属性的GetterSetter,在类中定义
public class User {
    @Getter
    @Setter
    private int id;
    
    private int age;
    private String username;
    private String password;
}
  • 不产生某一属性的Getter
  • @Getter(AccessLevel.NONE)
@Getter
@Setter
public class User {
    private int id;
    private int age;
    private String username;
    @Getter(AccessLevel.NONE)
    private String password;
}
  • 类中如果有静态的成员变量,被static 修饰,注解不起作用,只对成员变量起作用
  • final 修饰只会产生Getter,不能修改所以不会产生Setter

ToString

如果查看成员变量的赋值情况,来覆写toString(),否则打印出的是该类的hash码

@ToString
public class User {
    private int id;
    private int age;
    private String username;
    private String password;
}
User(id=1, age=18, username=Mr.Q, password=123)

排除某一字段的输出

  • @ToString(exclude = {"password"})

指定输出字段

  • @ToString(of = {"password"})

Data

  • @Data:课代表注解

集成了SetterGettertoString()equals()hashCode()@RequiredArgsConstructor指定参数(被@NonNUll 或者 无初值的final修饰)没有此注解默认为无参构造

@Data
public class User {
    private int id;
    private int age;
    private String username;
    private String password;
}

EqualsAndHashCode

  • @EqualsAndHashCode
  • equals()
  • hashCode()

【小葵花代码课堂开课了】

hashCode()方法和equal()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致,那么equal()既然已经能实现对比的功能了,为什么还要hashCode()呢?

因为重写的equal()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高,那么hashCode()既然效率这么高为什么还要equal()呢?

  • 两个obj,如果equals()相等,hashCode()一定相等
  • 两个obj,如果hashCode()相等,equals()则不一定相等(Hash散列值有冲突的情况)

判断两个对象是否相等的规则是:

  1. 如果hashCode()相等,则查看第二步,否则不相等;
  2. 查看equals()是否相等,如果相等,则两obj相等,否则还是不相等

Constructor

  • @NoArgsConstructor:无参构造
  • @RequiredArgsConstructor:指定参数(被@NonNUll 或者 无初值的final修饰)
  • @AllArgsConstructor:全参构造
@NoArgsConstructor
public class User {
    private int id;
    private int age;
    private String username;
    private String password;
}

Builder

  • @Builder:链式编程给字段赋值
@Data
@Builder
public class User {
    private int id;
    private int age;
    private String username;
    private String password;
}
@Test
    public void test() {
        User user = User.builder().id(1).username("Mr.Q").password("123").age(18).build();
        System.out.println(user);
    }
User(id=1, age=18, username=Mr.Q, password=123)

Log

  • @Log:日志信息
@Builder
@Log
public class User {
    private int id;
    private int age;
    private String username;
    private String password;

    public void fun(String s) {
        log.info("test");
    }
}
@Test
public void test() {
	User user = User.builder().id(1).username("Mr.Q").password("123").age(18).build();
	//打印类的日志信息
	user.fun("test");
}
三月 21, 2020 5:43:33 下午 com.iqqcode.lombok.User fun
信息: test

Cleanup

  • @Cleanup:自动关闭流操作
@Test
public void test() throws IOException {
	@Cleanup InputStream in = new FileInputStream("filePath1");
	@Cleanup OutputStream out = new FileOutputStream("filePath2");
	byte[] cache = new byte[1024];
	while(true) {
		int r = in.read(cache);
		if(r == -1) break;
		out.write(cache,0,r);
		}
	}

不用再写in.close();out.close();

其实不是不用写了,而是Lombok帮你写了。在 .class文件中,关闭流的操作还是存在的!