在开始前,我想先问问什么是lombok
呢?
大家应该都听说过,它是一个Java库,通过注解的方式,帮助开发者消除Java代码中的样板代码,从而提高开发效率。
用的最熟悉的注解应该就是@Data
了吧,它是一个复合注解,可以完成多个注解的功能@Getter
、 @Setter
、 @ToString
、 @EqualsAndHashCode
、@RequiredArgsConstructor
那么这些注解都很熟悉了,下面介绍一些在lombok
中不那么常用,但有时候异常好用的注解
如下使用,可以进行链式调用
package com.banmoon.lombok;
import lombok.Data;
import lombok.experimental.Accessors;
import org.junit.Test;
/**
* @author banmoon
* @date 2024/08/08 11:09:58
*/
public class LombokAccessorsTest {
@Test
public void test() {
// 最常用的,set链式方法
AccessorsChainBO chainBO = new AccessorsChainBO()
.setId(1)
.setName("banmoon")
.setEnabled(true);
System.out.println(chainBO);
}
}
@Data
@Accessors(chain = true)
class AccessorsChainBO {
private Integer id;
private String name;
private Boolean enabled;
}
还有一个fluent
属性可以实现链式调用,不过不建议开启
它会导致set
前缀没有了,有许多库都是使用反射set
、get
方法来进行的,会导致第三方库找不到方法,从而导致报错
package com.banmoon.lombok;
import lombok.Data;
import lombok.experimental.Accessors;
import org.junit.Test;
/**
* @author banmoon
* @date 2024/08/08 11:09:58
*/
public class LombokAccessorsTest {
@Test
public void test() {
// set前缀没有了,建议不要使用,有许多库都是使用反射set、get方法来进行的
AccessorsFluentBO fluentBO = new AccessorsFluentBO()
.id(1)
.name("banmoon")
.enabled(true);
System.out.println(fluentBO);
}
}
@Data
@Accessors(fluent = true)
class AccessorsFluentBO {
private Integer id;
private String name;
private Boolean enabled;
}
在jdk10
之后的版本,我们有个var
的关键字,它允许开发者在声明变量时使用类型推断,使得代码更为简洁和易读。使用 var
声明变量时,编译器会根据变量的初始化表达式推断出变量的类型,从而避免显式地写出类型名称。
那么lombok
中,引入了两个var
、val
注解,同样可以达成类似的效果
对的没看错,是注解,不是关键字
如下进行使用
package com.banmoon.lombok;
import lombok.val;
import lombok.var;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
/**
* @author banmoon
* @date 2024/08/08 11:42:47
*/
public class LombokVarValTest {
@Test
public void test() {
var list = new ArrayList<Integer>();
list.add(1);
list.add(2);
System.out.println(list);
val map = new HashMap<String, Object>();
map.put("name", "banmoon");
map.put("age", 18);
System.out.println(map);
}
}
同样是类型推断,
var
与val
有什么区别
var
和jdk10
之后的那个关键字是一样的,仅为类型推断val
相比之下,多出了一个final
关键字,即声明了一个不可变对象在Java
代码中,不需要关注垃圾回收,但有一个一定要主动关闭,那便是文件IO
流
如果使用lombok
,可以快速达成关闭流的写法,如下进行使用
package com.banmoon.lombok;
import lombok.Cleanup;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @author banmoon
* @date 2024/08/08 12:01:12
*/
public class LombokCleanupTest {
@Test
public void test() throws IOException {
@Cleanup InputStream in = Files.newInputStream(Paths.get("/User/1.txt"));
@Cleanup OutputStream out = Files.newOutputStream(Paths.get("/User/2.txt"));
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
其实从Java7
开始,你可以使用try-with-resources
语句来自动关闭实现了AutoCloseable
接口的资源。这种方式确保即使在处理资源的过程中发生异常,资源也会被正确关毕
package com.banmoon.lombok;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @author banmoon
* @date 2024/08/08 12:01:12
*/
public class LombokCleanupTest {
@Test
public void test1() throws IOException {
Path inPath = Paths.get("/User/1.txt");
Path outPath = Paths.get("/User/2.txt");
try (InputStream in = Files.newInputStream(inPath);
OutputStream out = Files.newOutputStream(outPath)) {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
}
有些时候,我们需要类的属性名去完成一些逻辑,要么老老实实的写一遍常量,要么反射类获取属性名
在lombok
中,使用@FieldNameConstants
注解在编译的时候,就生成对应类属性的常量,如下进行使用
package com.banmoon.lombok;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import lombok.experimental.FieldNameConstants;
import org.junit.Test;
import java.lang.reflect.Field;
/**
* @author banmoon
* @date 2024/08/08 13:52:28
*/
public class LombokFieldNameConstantsTest {
@Test
public void test() throws IllegalAccessException {
FieldNameConstantsBO fieldNameConstantsBO = new FieldNameConstantsBO();
fieldNameConstantsBO.setId(1);
fieldNameConstantsBO.setName("banmoon");
fieldNameConstantsBO.setEnabled(true);
// 通过反射获取值
Field field = ReflectUtil.getField(FieldNameConstantsBO.class, FieldNameConstantsBO.Fields.name);
field.setAccessible(true);
System.out.println(StrUtil.format("{}:{}", FieldNameConstantsBO.Fields.name, field.get(fieldNameConstantsBO)));
}
}
@Data
@FieldNameConstants
class FieldNameConstantsBO {
private Integer id;
private String name;
private Boolean enabled;
}
另外,某些不需要生成常量的属性,我们可以使用lombok.experimental.FieldNameConstants.Exclude
来达成
在日常开发中,常常有检查异常需要显式的去处理,要么throws
,要么catch
。处理不说十分繁琐,总归还是有的
但在lombok
中,可以使用@SneakyThrows
注解来完成这个异常抛出,如下使用
package com.banmoon.lombok;
import lombok.SneakyThrows;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
/**
* @author banmoon
* @date 2024/08/08 14:19:27
*/
public class LombokSneakyThrowsTest {
@Test
@SneakyThrows
public void test() {
TimeUnit.SECONDS.sleep(1);
}
}
同步锁synchronized
大家都很熟悉,但lombok
连这个都要简化,我感觉没必要
package com.banmoon.lombok;
import lombok.Synchronized;
/**
* @author banmoon
* @date 2024/08/08 15:06:11
*/
public class LombokSynchronizedTest {
private static final Object lock = new Object();
@Synchronized
public void test() {
System.out.println(1);
}
@Synchronized("lock")
public void test1() {
System.out.println(1);
}
@Synchronized
public static void staticTest() {
System.out.println(1);
}
}
编译后是这个样子的
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.banmoon.lombok;
public class LombokSynchronizedTest {
private final Object $lock = new Object[0];
private static final Object $LOCK = new Object[0];
private static final Object lock = new Object();
public LombokSynchronizedTest() {
}
public void test() {
synchronized(this.$lock) {
System.out.println(1);
}
}
public void test1() {
synchronized(lock) {
System.out.println(1);
}
}
public static void staticTest() {
synchronized($LOCK) {
System.out.println(1);
}
}
}
可以看到是同步代码块,如果没有指定value
,它会自己生成一个Object
。
静态方法使用的话,也是使用静态的Object
变量
为什么没有@Builder
,我在调试的时候出现了一点问题,这个也比较常用,需要单开一篇来解决
我是半月,另附带官网地址
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。