一、Lombok简介
Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码
二、Lombok插件安装(Idea)
在线安装:File->Settings->Plugins
离线安装:如下地址可以找到所有对应版本的安装包,然后在上图界面点击设置按钮,选择Disk安装
下载地址:https://plugins.jetbrains.com/plugin/6317-lombok/versions
三、引入依赖
<dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> <version>1.18.8version> <scope>providedscope> dependency>
四、Lombok注解介绍以及使用
@Data
注解在类,注解包含@EqualsAndHashCode、@getter、@setter、@NoArgsConstructor、@ToString注解
@Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法
@Datapublic class UserInfo { private String name; private String password;}
@Getter @Setter
可以注解在类上,注解会为属性(所有非静态成员变量)生成对应的getter、setter方法
@Getter@Setterpublic class UserInfo2 { private String name; private String password;}
@NoArgsConstructor,@RequiredArgsConstructor,@AllArgsConstructor
这三个注解都是用在类上的,第一个和第三个都很好理解,就是为该类产生无参的构造方法和包含所有参数的构造方法,第二个注解则使用类中所有带有@NonNull
注解的或者带有final
修饰的成员变量生成对应的构造方法,当然,和前面几个注解一样,成员变量都是非静态的,另外,如果类中含有final
修饰的成员变量,是无法使用@NoArgsConstructor
注解的。
三个注解都可以指定生成的构造方法的访问权限,同时,第二个注解还可以用@RequiredArgsConstructor(staticName="methodName")
的形式生成一个指定名称的静态方法,返回一个调用相应的构造方法产生的对象
// 使用注解@RequiredArgsConstructor(staticName = "sunsfan")@AllArgsConstructor(access = AccessLevel.PROTECTED)@NoArgsConstructorpublic class Shape { private int x; @NonNull private double y; @NonNull private String name;}// 不使用注解public class Shape { private int x; private double y; private String name; public Shape(){ } protected Shape(int x, double y, String name){ this.x = x; this.y = y; this.name = name; } public Shape(double y, String name){ this.y = y; this.name = name; } public static Shape sunsfan(double y, String name){ return new Shape(y, name); }}
@ToString,@EqualsAndHashCode
生成toString()
,equals()
和hashcode()
方法,同时后者还会生成一个canEqual()
方法,用于判断某个对象是否是当前类的实例,生成方法时只会使用类中的非静态和非transient
成员变量(用transient
关键字标记的成员变量不参与序列化过程),这两个注解同时也可以添加限制条件
// 来排除param1和param2两个成员变量@ToString(exclude={"param1","param2"})// 来指定使用param1和param2两个成员变量@ToString(of={"param1","param2"})
@Cleanup
注解用于确保已分配的资源被释放(IO的连接关闭)
// 使用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); }}// 不使用public static void main(String[] args) throws IOException { InputStream in = new FileInputStream(args[0]); try { OutputStream out = new FileOutputStream(args[1]); try { byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } } finally { if (out != null) { out.close(); } } } finally { if (in != null) { in.close(); } }}
@NonNull
用于标记类中不能允许为 null
的字段或者参数上,任何使用该字段的地方都生成空指针判断代码,若@NonNull
标记的变量为 null,抛出 NullPointException
(NPE) 异常。
// 使用public String getName(@NonNull Person person) { return person.getName;}// 不使用public String getName(Person person) { if (person == null) { throw new NullPointerException("person"); } return person.getName; }
@SneakyThrows
主要用于在没有 throws 关键字的情况下,隐蔽地抛出受检查异常,为我们平常开发中需要异常抛出时省去的 throw 操作
// 使用注解public class SneakyThrows implements Runnable { @SneakyThrows(UnsupportedEncodingException.class) public String utf8ToString(byte[] bytes) { return new String(bytes, "UTF-8"); } @SneakyThrows public void run() { throw new Throwable(); }}// 不使用注解public class SneakyThrows implements Runnable { public String utf8ToString(byte[] bytes) { try{ return new String(bytes, "UTF-8"); }catch(UnsupportedEncodingException uee){ throw Lombok.sneakyThrow(uee); } } public void run() { try{ throw new Throwable(); }catch(Throwable t){ throw Lombok.sneakyThrow(t); } }}
@Synchronized
这个注解用在类方法或者实例方法上,效果和synchronized
关键字相同,区别在于锁对象不同,对于类方法和实例方法,synchronized
关键字的锁对象分别是类的class
对象和this
对象,而@Synchronized
得锁对象分别是私有静态final
对象lock
和私有final
对象lock
和私有final
对象lock
,当然,也可以自己指定锁对象
// 使用注解public class Synchronized { private final Object readLock = new Object(); @Synchronized public static void hello() { System.out.println("world"); } @Synchronized public int answerToLife() { return 42; } @Synchronized("readLock") public void foo() { System.out.println("bar"); }}// 不使用public class Synchronized { private static final Object $LOCK = new Object[0]; private final Object $lock = new Object[0]; private final Object readLock = new Object(); public static void hello() { synchronized($LOCK) { System.out.println("world"); } } public int answerToLife() { synchronized($lock) { return 42; } } public void foo() { synchronized(readLock) { System.out.println("bar"); } } }
@Builder
一个非常强大的注解,提供了一种基于建造者模式的构建对象的 API。使用 @Builder
注解为给我们的实体类自动生成 builder()
方法,并且直接根据字段名称方法进行字段赋值,最后使用 build()
方法构建出一个实体对象。
@Data
@Builder
public class User6 {
private Integer id;
private String username;
private String password;
}
@Test
public void testBuilder() {
User6 user6 = User6.builder().id(1).username("user6").password("zxc123").build();
log.warn("testLog: {}", user6); // User6(id=1, username=user6, password=zxc123)
}
参考:
https://projectlombok.org/
https://www.jianshu.com/p/46f709210daf
https://www.jianshu.com/p/68babcf5a4ad