实体类使用lombok注解加快开发
前言
Github:https://github.com/HealerJean
1、安装
lombok是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写。
1、优点:
即通过采用注解的方式,消除代码中的构造方法,getter/setter等代码,使我们写的类更加简洁,
2、缺点:
当然,这带来的副作用就是不易阅读…不过,还是能看得懂吧,废话不多说,先看一下lombok支持的一些常见的注解。
1.1、插件lombok
1.2、依赖导入
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2、注解
2.1、@Data
注解在类上; @Data等价
@Setter
、@Getter
、@RequiredArgsConstructor
、@ToString
、@EqualsAndHashCode
提供类所有属性的
getting
和setting
方法,此外还提供了equals
、canEqual
、hashCode、toString 方法
举例
@Data
public class EntityBean {
String name;
public static void main(String[] args) {
EntityBean entityBean = new EntityBean();
entityBean.setName("HealerJean");
System.out.println(entityBean.getName());
}
}
控制台 :HeaelrJean
2.2、Getter
和 @Setter
注解再字段、类上
用于生成
get
和set
方法,默认是public
的,除非向下面一样指定
public class GetSeter {
@Getter
@Setter
private String name;
@Setter(AccessLevel.PROTECTED)
private int age;
@Getter(AccessLevel.PUBLIC)
private String language;
}
等价于
public class GetSeter{
private String name;
private int age;
private String language;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
protected void setAge(int age){
this.age = age;
}
public String getLanguage(){
return language;
}
}
2.3、@AllArgsConstructor
和@NoArgsConstructor
@AllArgsConstructor
有参构造器
@NoArgsConstructor
无参构造器
@AllArgsConstructor(access = AccessLevel.PROTECTED) //指定方法的封装为protect
@NoArgsConstructor
public class ArgsConstructor {
private int x;
public static void main(String[] args) {
//有参构造器
ArgsConstructor argsConstructor = new ArgsConstructor(2);
}
}
等价于
public class Shape {
private int x;
private String name;
public Shape(){
}
protected Shape(int x,String name){
this.x = x;
this.name = name;
}
}
2.4、@log
、@Slf4j
@Slf4j
:这个注解用在类上,可以省去从日志工厂生成日志对象这一步
@CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@JBossLog
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
@Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
@Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
@Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
@Slf4j
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
2.5、@Accessors
属性
chain
,用来改变set方法的void变成this.对我而言,在第一次根据别人博客学cas的时候遇到过
@Data
@Accessors(chain = true)
public class SessionKeyResult {
private String openid;
private String sessionKey;
public static void main(String[] args) {
SessionKeyResult sessionKeyResult = new SessionKeyResult();
sessionKeyResult.setOpenid("HealerJean").setSessionKey("Jean")
}
}
2.6、@builder
2.6.1、和 @Data
通常是
@Data
和@Builder
会一起用在同个类上,既方便我们流式写代码,也方便框架做事,只使用@Builder
则不能答应内容
//1、不加@Data
@Builder
public class DemoEntity05Builder {
private String name;
}
/**
* 不加@Data注解打印数据为null
*/
@Test
public void testBuilder(){
DemoEntity05Builder demoEntity05Builder = DemoEntity05Builder.builder().name("HealerJean").build();
log.info(JSONObject.fromObject(demoEntity05Builder).toString());
//null
}
//2、加上@Data
@Data
@Builder
public class DemoEntity05Builder {
private String name;
}
/**
* 不加@Data注解打印数据为null
*/
@Test
public void testBuilder(){
DemoEntity05Builder demoEntity05Builder = DemoEntity05Builder.builder().name("HealerJean").build();
log.info(JSONObject.fromObject(demoEntity05Builder).toString());
//{"name":"HealerJean"}
}
2.6.2、和@NoArgsConstructor
、@AllArgsConstructor
使用构造器的时候,不加
@NoArgsConstructor
、@AllArgsConstructor
会报错,所以两个全部加上
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class DemoEntity05Builder {
private String name;
}
@Test
public void testBuilder2(){
DemoEntity05Builder demoEntity05Builder = new DemoEntity05Builder();
demoEntity05Builder.setName("healerjean2");
log.info(JSONObject.fromObject(demoEntity05Builder).toString());
}
2.7、@ToString
在java.lang.Object中有个实例方法toString,这个方法的作用是一个对象的自我描述。在源码中有这样一句注释,It is recommended that all subclasses override this method.即推荐所有的子类重新该方法。
因为该方法在Object中的实现是返回字符串——类名和该对象的hashCode用“@”符连接起来的字符串,不具有可读性。
所以,需要重写该方法,使得该方法能够清楚地表述自己的每一个成员变量。现在,我们在已经创建的Student类,重写该方法。
2.7.1、不加@ToString
public class DemoEntity06_ToString {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Test
public void testToString(){
DemoEntity06_ToString demoEntity05Builder = new DemoEntity06_ToString();
demoEntity05Builder.setName("healejean");
System.out.println(demoEntity05Builder);
//com.hlj.data.bean.demo.DemoEntity06_ToString@2ddc8ecb
log.info(demoEntity05Builder.toString());
// com.hlj.data.bean.demo.DemoEntity06_ToString@2ddc8ecb
}
2.7.1、加@ToString
@ToString
public class DemoEntity06_ToString {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Test
public void testToString(){
DemoEntity06_ToString demoEntity05Builder = new DemoEntity06_ToString();
demoEntity05Builder.setName("healejean");
System.out.println(demoEntity05Builder);
//DemoEntity06_ToString(name=healejean)
log.info(demoEntity05Builder.toString());
//DemoEntity06_ToString(name=healejean)
}
3、问题汇总
3.1、常见问题
3.1.1、@Accessors
导致 easy excel
读取为字段值空
去掉
@Accessors
注解
3.2、Generating
equals
3.2.1、问题出现
@Accessors(chain = true)
@Data
public class RouteRuleDataV0Dto extends RouteRuleDataBaseDTO implements Serializable {
3.2.2、问题解决
3.2.2.1、原因
原因;当我们给一个继承了父类的子类上使用 @Data
` @ToString ||
@EqualsAndHashCode注解时,
IDE` 会警告
3.2.2.2、解决方案
在子类上声明
@EqualsAndHashCode(callSuper = true)
@EqualsAndHashCode
是Lombok
提供的一个非常有用的注解,可以自动生成equals
和hashCode
方法,用于生成equals(Object other)
方法和hashCode()
方法的实现。这两个方法通常用于判断两个对象是否相等,以及在哈希表中(如HashSet
、HashMap
等)正确地存储和检索对象。
callSuper = true
:这个属性指定了在生成equals()
和hashCode()
方法时,应该调用父类的相应方法。默认情况下,callSuper
是false
,这意味着生成的equals()
和hashCode()
方法只会比较当前类声明的字段。如果你的类继承自另一个类,并且你希望equals()
和hashCode()
方法的行为能够考虑父类的状态(即父类声明的字段),那么你就应该将callSuper
设置为true
。
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@Data
public class RouteRuleDataV0Dto extends RouteRuleDataBaseDTO implements Serializable {