lombok的使⽤详解,解决@Builder.Default默认值问题
前⾔
Lombok是⼀款Java开发插件,使得Java开发者可以通过其定义的⼀些注解来消除业务⼯程中冗长和繁琐的代码,尤其对于简单的Java模型对象(POJO)。在开发环境中使⽤Lombok插件后,Java开发⼈员可以节省出重复构建,诸如hashCode和equals这样的⽅法以及各种业务对象模型的accessor和ToString等⽅法的⼤量时间。对于这些⽅法,它能够在编译源代码期间⾃动帮我们⽣成这些⽅法,并没有如反射那样降低程序的性能。
它所有的增强都是通过注解实现,所以了解其使⽤主要了解⼀下注解即可
注解列表
Maven下的依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>1.18.4</version>
</dependency>
Gradle下 的依赖(kts)
dependencies {
//*Lombok*
// <p>注解处理将不再compile classpath中,需要⼿动添加到annotation processor path</p>
compileOnly("org.projectlombok:lombok:1.18.4")
annotationProcessor("org.projectlombok:lombok:1.18.4")
testCompileOnly("org.projectlombok:lombok:1.18.4")
testAnnotationProcessor("org.projectlombok:lombok:1.18.4")
}
先介绍这⼀波最常⽤的注解:
@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor
这三个注解都是⽤在类上的,第⼀个和第三个都很好理解,就是为该类产⽣⽆参的构造⽅法和包含所有参数的构造⽅法,第⼆个注解则使⽤类中所有带有@NonNull注解的或者带有final修饰的成员变量⽣成对应的构造⽅法,当然,和前⾯⼏个注解⼀样,成员变量都是⾮静态的。
另外,如果类中含有final修饰的成员变量,是⽆法使⽤@NoArgsConstructor注解的。
三个注解都可以指定⽣成的构造⽅法的访问权限,还可指定⽣成⼀个静态⽅法
使⽤案例:
@AllArgsConstructor
public class Demo {
private String name;
private int age;
}
@AllArgsConstructor
class Parent {
private Integer id;
}
编译后的两个class⽂件如下:
private String name;
private int age;
public Demo(String name,int age){
this.name = name;
this.age = age;
}
}
//第⼆个类
class Parent {
private Integer id;
public Parent(Integer id){
this.id = id;
}
}
由此课件,此注解并不会把⽗类的属性id拿到Demo的构造器⾥⾯去,这是需要注意的地⽅。并且它也没有默认的构造器了
@AllArgsConstructor(access = AccessLevel.PROTECTED, staticName ="test")
public class Demo {
private final int finalVal =10;
private String name;
private int age;
}
⽣成如下:
public class Demo {
private final int finalVal =10;
private String name;
private int age;
private Demo(String name,int age){
this.name = name;
this.age = age;
}
protected static Demo test(String name,int age){
return new Demo(name, age);
}
}
看出来的效果为:可以指定⽣成的构造器的访问权限。但是,但是如果指定了⼀个静态⽅法,那么构造器会⾃动会被private,只通过静态⽅法对外提供反问,并且我们发现final的属性值,是不会放进构造函数⾥⾯的。
NoArgsConstructor的使⽤⽅式同上,RequiredArgsConstructor看看效果:
@RequiredArgsConstructor
public class Demo {
private final int finalVal =10;
@NonNull
private String name;
@NonNull
private int age;
}
编译后:
@NonNull
private String name;
@NonNull
private int age;
public Demo(@NonNull String name,@NonNull int age){
if(name == null){
throw new NullPointerException("name is marked @NonNull but is null");
}else{
this.name = name;
this.age = age;
}
}
}
解释:该注解会识别@nonNull字段,然后以该字段为元素产⽣⼀个构造函数。备注:如果所有字段都没有@nonNull注解,那效果同NoArgsConstructor
@Builder
@Builder提供了⼀种⽐较推崇的构建值对象的⽅式
⾮常推荐的⼀种构建值对象的⽅式。缺点就是⽗类的属性不能产于builder
@Builder
public class Demo {
private final int finalVal =10;
private String name;
private int age;
}
编译后:
private String name;
private int age;
Demo(String name,int age){
this.name = name;
this.age = age;
}
public static Demo.DemoBuilder builder(){
return new Demo.DemoBuilder();
}
public static class DemoBuilder {
private String name;
try catch的使用方法private int age;
DemoBuilder(){
}
public Demo.DemoBuilder name(String name){
this.name = name;
return this;
}
public Demo.DemoBuilder age(int age){
this.age = age;
return this;
}
public Demo build(){
return new Demo(this.name,this.age);
}
public String toString(){
String var10000 =this.name;
return this.age;
}
}
}
因此我们构造⼀个对象就可以优雅的这么来:
public static void main(String[] args){
Demo demo = Demo.builder().name("aa").age(10).build();
System.out.println(demo);
}
⾥⾯有⼀些⾃定义参数,我表⽰,完全没有必要去⾃定义。
@Cleanup
@Cleanup能够⾃动释放资源
这个注解⽤在变量前⾯,可以保证此变量代表的资源会被⾃动关闭,默认是调⽤资源的close()⽅法。如果该资源有其它关闭⽅法,可使⽤@Cleanup(“methodName”)来指定要调⽤的⽅法,就⽤输⼊输出流来举个例⼦吧:
public static void main(String[] args)throws Exception {
@Cleanup InputStream in =new FileInputStream(args[0]);
@Cleanup OutputStream out =new FileOutputStream(args[1]);
byte[] b =new byte[1024];
while(true){
int r = in.read(b);
if(r ==-1)break;
out.write(b,0, r);
}
}
编译后:
public static void main(String[] args)throws Exception {
FileInputStream in =new FileInputStream(args[0]);
try{
FileOutputStream out =new FileOutputStream(args[1]);
try{
byte[] b =new byte[1024];
while(true){
int r = in.read(b);
if(r ==-1){
return;
}
out.write(b,0, r);
}
}finally{
if(Collections.singletonList(out).get(0)!= null){
out.close();
}
}
}finally{
if(Collections.singletonList(in).get(0)!= null){
in.close();
}
}
}
就这么简单的⼀个注解,就实现了优雅的关流操作哟。
@Data
@Data 强悍的组合功能包
相当于注解集合。效果等同于**@Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor** 由于⽣成的代码篇幅太长,这⾥就不给demo了,反正效果同上5个注解的效果,强悍
需要注意的是,这⾥不包括@NoArgsConstructor和@AllArgsConstructor
@Value
@Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会⽣成set⽅法。
所以@Value更适合只读性更强的类,所以特殊情况下,还是可以使⽤的。
@ToString/@EqualsAndHashCode
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论