首页 > 其他分享 >探究lombok-01

探究lombok-01

时间:2022-12-01 21:58:26浏览次数:42  
标签:01 java UserVO 探究 length modifiers lombok type class

Java 8

org.springframework.boot 2.7.3

lombok 1.18.24

Eclipse Version: 2022-09 (4.25.0)

--

 

0、序

Project Lombok:

https://projectlombok.org/

 

经常用lombok,特别方便,已经离不开了,现在来深入了解下它。ben发布于博客园

为什么加一个(些)注解后,平平无奇的POJO就有这么多功能呢?

 

pom.xml 中和 lombok 相关的内容:

 

本文涉及的注解:ben发布于博客园

@Data、@Builder、@EqualsAndHashCode、@Slf4j

 

注,本文不涉及类继承。

 

一些博文说使用lombok存在问题,大家自行注意下:ben发布于博客园

 

1、测试代码

POJO:UserVO.java

import java.util.Date;
import java.util.List;

public class UserVO {

	// 字段
	
	private Integer id;
	
	private String name;
	
	private List<String> tags;
	
	private Date createTime;
	
}

测试类:LombokMain.java

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.function.Consumer;

public class LombokMain {

	private static Consumer<Object> cs = System.out::println;
	
	public static void main(String[] args) {
		test(UserVO.class);
	}
	
	private static void test(Class cls) {
		cs.accept("\n\n测试:class=" + cls);
		Objects.requireNonNull(cls);
		
		Class[] classes = cls.getDeclaredClasses();
		prtClasses(classes);
		
		cs.accept("----");
		
		Constructor<?>[] constructors = cls.getDeclaredConstructors();
		prtConstructors(constructors);
		
		cs.accept("----");
		
		Field[] fields = cls.getDeclaredFields();
		prtFields(fields);
		
		cs.accept("----");
		
		Method[] methods = cls.getDeclaredMethods();
		prtMethods(methods);
	}

	private static void prtClasses(Class[] classes) {
		if (classes == null || classes.length == 0) {
			cs.accept("prtClasses: length=0");
			return;
		}
		
		cs.accept("prtClasses: length=" + classes.length);
		
		for (Class el : classes) {
			cs.accept("内部类: " + el.getCanonicalName() + ", " + el.getName() 
			+ ", " + el.getSimpleName() + ", " + el.getTypeName() + ", modifiers=" + el.getModifiers());
		}
	}

	private static void prtConstructors(Constructor<?>[] constructors) {
		if (constructors == null || constructors.length == 0) {
			cs.accept("prtFields: length=0");
			return;
		}
		
		cs.accept("prtConstructors: length=" + constructors.length);
		
		for (Constructor el : constructors) {
			cs.accept("构造方法名称:" + el.getName() + ", 参数数量:" + el.getParameterCount() + ", modifiers=" + el.getModifiers());
		}
	}

	private static void prtFields(Field[] fields) {
		if (fields == null || fields.length == 0) {
			cs.accept("prtFields: length=0");
			return;
		}
		
		cs.accept("prtFields: length=" + fields.length);
		
		for (Field el : fields) {
			cs.accept("字段:" + el.getName() + ", type=" + el.getType() + ", modifiers=" + el.getModifiers());
		}
	}

	private static void prtMethods(Method[] methods) {
		if (methods == null || methods.length == 0) {
			cs.accept("prtMethods: length=0");
			return;
		}
		
		cs.accept("prtMethods: length=" + methods.length);
		
		for (Method el : methods) {
			cs.accept("方法名称:" + el.getName() + ", 参数数量:" + el.getParameterCount() + ", modifiers=" + el.getModifiers());
		}
	}

}

 

注,UserVO.java 和 LombokMain.java 在同一个 package 中。ben发布于博客园

 

在 UserVO.java 没有使用 lombok 注解时,测试结果如下:

测试:class=class com.lib.webdemo.vo.UserVO
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO, 参数数量:0, modifiers=1
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=0

 

modifiers 是 什么意思呢?ben发布于博客园

Returns the Java language modifiers for this class or interface, encodedin an integer. 
The modifiers consist of the Java Virtual Machine'sconstants for 
public, protected, private, final, static, abstract and interface; 
they should be decodedusing the methods of class Modifier. 

具体值可以看 java.lang.reflect.Modifier 类。

 

modifiers=1 即 public修饰符;

modifiers=2 即 priavte修饰符。ben发布于博客园

可以相加,但本次测试没有这个情况。

 

2、@Data

给UserVO添加 @Data 注解,测试结果:

测试:class=class com.lib.webdemo.vo.UserVO
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO, 参数数量:0, modifiers=1
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=12
方法名称:equals, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:hashCode, 参数数量:0, modifiers=1
方法名称:getName, 参数数量:0, modifiers=1
方法名称:getId, 参数数量:0, modifiers=1
方法名称:setName, 参数数量:1, modifiers=1
方法名称:getCreateTime, 参数数量:0, modifiers=1
方法名称:canEqual, 参数数量:1, modifiers=4
方法名称:setCreateTime, 参数数量:1, modifiers=1
方法名称:setId, 参数数量:1, modifiers=1
方法名称:getTags, 参数数量:0, modifiers=1
方法名称:setTags, 参数数量:1, modifiers=1

多了12个方法,除了setter、getter外,还有equals、hashCode、canEqual、toString。ben发布于博客园

 

@Data 是 使用频率最高的一个注解,一般用了它就不需要使用其它的了。它的效果相当于使用 @Getter、@Setter、@EqualsAndHashCode、@ToString 注解之和。

 

3、@EqualsAndHashCode

在 第1节 的基础上 添加 @EqualsAndHashCode,测试结果:

测试:class=class com.lib.webdemo.vo.UserVO
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO, 参数数量:0, modifiers=1
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=3
方法名称:equals, 参数数量:1, modifiers=1
方法名称:hashCode, 参数数量:0, modifiers=1
方法名称:canEqual, 参数数量:1, modifiers=4

多了3个方法:equals、hashCode、canEqual,其中,canEqual的modifiers=4(protected)ben发布于博客园。

 

4、@Builder

在 第1节 的基础上 添加 @Builder,测试结果:

测试:class=class com.lib.webdemo.vo.UserVO
prtClasses: length=1
内部类: com.lib.webdemo.vo.UserVO.UserVOBuilder, com.lib.webdemo.vo.UserVO$UserVOBuilder, UserVOBuilder, com.lib.webdemo.vo.UserVO$UserVOBuilder, modifiers=9
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO, 参数数量:4, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=1
方法名称:builder, 参数数量:0, modifiers=9

可以看到,

多了一个 内部类 com.lib.webdemo.vo.UserVO.UserVOBuilder;ben发布于博客园

构造方法的 modifiers=0,即 不可以使用 new UserVO() 建立对象;

多了一个方法 builder,其 modifiers=9(public、static),用来生成 UserVOBuilder 对象,进而创建 UserVO 对象。

 

检查编译生成的class文件:ben发布于博客园

UserVO$UserVOBuilder.class // 内部类编译后
UserVO.class

 

那么,UserVOBuilder 的测试结果如何?

测试:class=class com.lib.webdemo.vo.UserVO$UserVOBuilder
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO$UserVOBuilder, 参数数量:0, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=6
方法名称:name, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:id, 参数数量:1, modifiers=1
方法名称:createTime, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1
方法名称:tags, 参数数量:1, modifiers=1

这里的 build方法 是用来创建 UserVO对象的。

 

生成UserVO对象

前面提到无法使用 new UserVO() 创建对象,在使用 @Builder注解时,可以使用下面的方式创建对象:ben发布于博客园

// 链式编程
UserVO user = UserVO.builder()
    .id(1)
    .name("builder")
    .tags(new ArrayList<String>())
    .createTime(new Date())
    .build();

注意,这里用到的 UserVO 的 builder方法、 UserVO$UserVOBuilder 的 build方法。

 

5、@Slf4j

在 第1节 的基础上 添加 @Slf4j,测试结果:

测试:class=class com.lib.webdemo.vo.UserVO
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO, 参数数量:0, modifiers=1
----
prtFields: length=5
字段:log, type=interface org.slf4j.Logger, modifiers=26
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=0

多了一个名为 log 的属性,用于 UserVO类 日志输出,其 modifiers=26(0x1A, final, static, private)ben发布于博客园。

 

6、注解组合

lombok的注解可以组合使用。ben发布于博客园

比如给第一节的UserVO添加下面三个注解:

import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

@Builder
@Getter
@ToString
public class UserVO {
//...
}

测试结果:ben发布于博客园

测试:class=class com.lib.webdemo.vo.UserVO
prtClasses: length=1
内部类: com.lib.webdemo.vo.UserVO.UserVOBuilder, com.lib.webdemo.vo.UserVO$UserVOBuilder, UserVOBuilder, com.lib.webdemo.vo.UserVO$UserVOBuilder, modifiers=9
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserVO, 参数数量:4, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=6
方法名称:toString, 参数数量:0, modifiers=1
方法名称:getName, 参数数量:0, modifiers=1
方法名称:getId, 参数数量:0, modifiers=1
方法名称:getTags, 参数数量:0, modifiers=1
方法名称:builder, 参数数量:0, modifiers=9
方法名称:getCreateTime, 参数数量:0, modifiers=1

ben发布于博客园

~END.~

 

参考资料

1、

 

ben发布于博客园

标签:01,java,UserVO,探究,length,modifiers,lombok,type,class
From: https://www.cnblogs.com/luo630/p/16941897.html

相关文章

  • 打算整理GAMES101课程的阅读材料在虎书第5版中的对应章节
    最近一段时间一直在学习GAMES101,这是一门非常值得推荐的课程,如果能把这门课程大部分内容学懂,会打开认识世界的新大门。这门课程能把以前学习的微积分,概率论,线性代数,微分方......
  • Bash 任意命令执行安全漏洞:CVE-2019-9924影响范围 小于Bash 4.4-beta2之前版本
    Bash任意命令执行安全漏洞:CVE-2019-9924影响范围小于Bash4.4-beta2之前版本http://git.savannah.gnu.org/cgit/bash.git/snapshot/bash-bash-4.4-rc2.tar.gzwgethttp......
  • #yyds干货盘点#【愚公系列】2022年12月 微信小程序-项目篇(公交查询)-01周边站点
    前言1.公交车站的意义转变现有出行模式,倡导公共交通和混合动力汽车、电动车、自行车等低碳或无碳方式,同时也丰富出行生活,增加出行项目。扭转奢华浪费之风,强化清洁、方便......
  • starctf2018_babystack
    starctf2018_babystack新知识这道题又学到一个知识点,就是有关控制canary,之前所了解的就是他会生成一个随机数,然会放到一个寄存器中如下图64位时fs:28,32位时fs:14,在返回......
  • buuoj-[2019红帽杯]easyRE
    1.elf文件64bit2.找到主程序continue上面解出来是这个:Info:Thefirstfourcharsareflag屁股有一段base64套娃,解出来是一个网址没啥用。。3.没思路了去百度,......
  • 8_Lombok
    使用步骤:在IDEA中安装Lombok插件在项目中导入lombok的jar包<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><vers......
  • buuoj-[GUET-CTF2019]re
    1.nowinexe64bit打开后发现有壳2.存在关键字符串输入的flag进入了sub_4009ae函数,点进去:一个一个除回去应该能得到flagflag{e65421110ba03099a1c039337}由......
  • 01背包问题动态规划法求解
    01背包问题动态规划法求解一问题描述:有N件商品,每种商品都有各自的重量和价值,有一个背包,总容量是V。现在从这N种商品中挑选若干件放入背包中,要求每种商品最多放入一次,要使放......
  • 探究一种定长队列操作(C ,C++版本)
    一问题来源:南京烽火通信面试二问题:现有一种定长队列,长度为2的n次方,此队列可被多线程访问,但必须确保线程级安全,即在任意时刻,队列的长度保持不变。三笔者分析1.队列的存储......
  • 01 新手PCB设计原则
    1.分析原理图功率线分布模块之间的联系2.布局模块化布局先定位、后先大器件再小器件预留走线位置、最小回流路径是否有爬电距离与空间间隙......