首页 > 其他分享 >探究lombok-02-类继承

探究lombok-02-类继承

时间:2022-12-02 23:34:31浏览次数:64  
标签:02 modifiers java lib 探究 参数 lombok com class

Java 8

org.springframework.boot 2.7.3

lombok 1.18.24

Eclipse Version: 2022-09 (4.25.0)

--ben发布于博客园

 

上一篇:探究lombok-01

https://www.cnblogs.com/luo630/p/16941897.html

注,本文测试结果的 LombokMain.java 的代码与上一篇相同。

 

0、序章

本文主要介绍类继承时使用lombok注解。涉及:ben发布于博客园

@Data、@Builder、@SuperBuilder

 

1、父子类都用@Data(可行)

孤使用频率最高的方式。ben发布于博客园

测试类:BaseDataVO、UserDataVO

// 1、BaseDataVO
import lombok.Data;

@Data
public class BaseDataVO {

	private Integer supId;
	private String supName;
	
}

// 2、UserDataVO
import java.util.Date;
import java.util.List;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

@Data
//@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class UserDataVO extends BaseDataVO {

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

 

测试结果:和 前一篇 一直,多了几个成员方法

都用@Data的测试结果
 测试:class=class com.lib.webdemo.vo2.BaseDataVO
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.BaseDataVO, 参数数量:0, modifiers=1
----
prtFields: length=2
字段:supId, type=class java.lang.Integer, modifiers=2
字段:supName, type=class java.lang.String, modifiers=2
----
prtMethods: length=8
方法名称:equals, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:hashCode, 参数数量:0, modifiers=1
方法名称:setSupId, 参数数量:1, modifiers=1
方法名称:setSupName, 参数数量:1, modifiers=1
方法名称:getSupId, 参数数量:0, modifiers=1
方法名称:getSupName, 参数数量:0, modifiers=1
方法名称:canEqual, 参数数量:1, modifiers=4


测试:class=class com.lib.webdemo.vo2.UserDataVO
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.UserDataVO, 参数数量: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
方法名称:setId, 参数数量:1, modifiers=1
方法名称:setTags, 参数数量:1, modifiers=1
方法名称:setCreateTime, 参数数量:1, modifiers=1
方法名称:canEqual, 参数数量:1, modifiers=4
方法名称:getTags, 参数数量:0, modifiers=1
方法名称:getCreateTime, 参数数量:0, modifiers=1

 

创建新对象及打印:在测试类 LombokMain 中添加下面的函数

private static void testDataVo() {
    cs.accept("\n\n测试:testDataVo...");

    BaseDataVO base = new BaseDataVO();
    base.setSupId(999);
    base.setSupName("super999");
    cs.accept("BaseDataVO base=" + base);

    UserDataVO user = new UserDataVO();
    // 父
    user.setSupId(888);
    user.setSupName("super888");
    // 子
    user.setId(1);
    user.setName("sub1");
    user.setTags(new ArrayList<>());
    user.setCreateTime(new Date());
    cs.accept("UserDataVO user=" + user);
}

测试结果:

测试:testDataVo...
BaseDataVO base=BaseDataVO(supId=999, supName=super999)
UserDataVO user=UserDataVO(super=BaseDataVO(supId=888, supName=super888), id=1, name=sub1, tags=[], createTime=Fri Dec 02 19:21:12 CST 2022)

说明,UserDataVO 中的 super 为 父类的值,是因为 使用了注解 @ToString(callSuper = true) 才有的。ben发布于博客园

 

小结

常用方式。可行。要配合 @ToString(callSuper = true)  使用才能输出父类属性,或自己手写toString函数。

 

2、父子类都用@Builder(不可行)

此方式不可行。

测试类:BaseBuilderVO、UserBuilderVO

// 1、BaseBuilderVO
import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class BaseBuilderVO {

	private Integer supId;
	private String supName;
	
}

// 2、UserBuilderVO
import java.util.Date;
import java.util.List;

import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

@Builder // 合理存在错误(1)
@ToString
public class UserBuilderVO extends BaseBuilderVO {

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

错误(1):Eclipse提示如下

Implicit super constructor BaseBuilderVO() is undefined. Must explicitly invoke another constructor

BaseBuilderVO 没有默认构造函数 导致。ben发布于博客园

 

给 BaseBuilderVO 添加 @NoArgsConstructor 注解,此时,BaseBuilderVO  存在错误:

The constructor BaseBuilderVO(Integer, String) is undefined

再添加 @AllArgsConstructor 注解,BaseBuilderVO 未报错,但 UserBuilderVO 仍然报错:

UserBuilderVO 从错误 和之前一样。

这样看来,在 BaseBuilderVO 添加 @NoArgsConstructor 、 @AllArgsConstructor 无法解决问题(参考资料#2)。

进一步测试,在 UserBuilderVO 上添加 @NoArgsConstructor 、 @AllArgsConstructor 也解决不了报错。ben发布于博客园

 

参考资料#2 提到一种 手动创建构造函数的方式:试验未成功。

从 @Builder 注解的源码来看,它可以用在 类型、成员方法、构造器上面:

@Target({TYPE, METHOD, CONSTRUCTOR})
@Retention(SOURCE)
public @interface Builder {
//...
}

还需进一步探索。TODO

 

小结

放弃使用 @Builder 实现 类继承。ben发布于博客园

 

3、使用@SuperBuilder(可行)

按照 参考资料#2 的介绍,这是一个  试验性质 的注解。

import lombok.experimental.SuperBuilder;

包名里面有一个 experimental。

 

父类使用 @SuperBuilder

建立一个父类:BaseSuperBuilderVO

import lombok.experimental.SuperBuilder;

@SuperBuilder
@ToString
public class BaseSuperBuilderVO {

	private Integer supId;
	private String supName;
	
}

类检查结果:

测试:class=class com.lib.webdemo.vo2.BaseSuperBuilderVO
prtClasses: length=2
内部类: com.lib.webdemo.vo2.BaseSuperBuilderVO.BaseSuperBuilderVOBuilder, com.lib.webdemo.vo2.BaseSuperBuilderVO$BaseSuperBuilderVOBuilder, BaseSuperBuilderVOBuilder, com.lib.webdemo.vo2.BaseSuperBuilderVO$BaseSuperBuilderVOBuilder, modifiers=1033
内部类: com.lib.webdemo.vo2.BaseSuperBuilderVO.BaseSuperBuilderVOBuilderImpl, com.lib.webdemo.vo2.BaseSuperBuilderVO$BaseSuperBuilderVOBuilderImpl, BaseSuperBuilderVOBuilderImpl, com.lib.webdemo.vo2.BaseSuperBuilderVO$BaseSuperBuilderVOBuilderImpl, modifiers=26
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.BaseSuperBuilderVO, 参数数量:1, modifiers=4
----
prtFields: length=2
字段:supId, type=class java.lang.Integer, modifiers=2
字段:supName, type=class java.lang.String, modifiers=2
----
prtMethods: length=1
方法名称:builder, 参数数量:0, modifiers=9

这里出现了 两个内部类:BaseSuperBuilderVOBuilder(modifiers=1033)、BaseSuperBuilderVOBuilderImpl(modifiers=26)。

Eclipse的快捷键 Ctrl+Shift + T 可以搜搜到 这两个类:ben发布于博客园

 

BaseSuperBuilderVOBuilder 的 类分析测试结果:

测试:class=class com.lib.webdemo.vo2.BaseSuperBuilderVO$BaseSuperBuilderVOBuilder
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.BaseSuperBuilderVO$BaseSuperBuilderVOBuilder, 参数数量:0, modifiers=1
----
prtFields: length=2
字段:supId, type=class java.lang.Integer, modifiers=2
字段:supName, type=class java.lang.String, modifiers=2
----
prtMethods: length=7
方法名称:toString, 参数数量:0, modifiers=1
方法名称:supId, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1025
方法名称:supName, 参数数量:1, modifiers=1
方法名称:access$1, 参数数量:1, modifiers=4104
方法名称:access$0, 参数数量:1, modifiers=4104
方法名称:self, 参数数量:0, modifiers=1028

相比于使用@Builder,多了 access$1、access$0、self 3个方法。 ben发布于博客园

 

说明,BaseSuperBuilderVOBuilderImpl 是 private的,不做分析。

 

建立 BaseSuperBuilderVO 对象:

private static void testCreateBaseSuperBuilderVO() {
    BaseSuperBuilderVO base = BaseSuperBuilderVO.builder()
        .supId(999)
        .supName("super999")
        .build();
    cs.accept("BaseSuperBuilderVO base=" + base);
}

测试结果:

BaseSuperBuilderVO base=BaseSuperBuilderVO(supId=999, supName=super999)

 

子类使用 @SuperBuilder

新建子类 UserSuperBuilderVO:

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

import lombok.ToString;
import lombok.experimental.SuperBuilder;

@SuperBuilder
@ToString(callSuper = true)
public class UserSuperBuilderVO extends BaseSuperBuilderVO {

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

分析类 UserSuperBuilderVO、UserSuperBuilderVOBuilder 的测试结果:ben发布于博客园

测试:class=class com.lib.webdemo.vo2.UserSuperBuilderVO
prtClasses: length=2
内部类: com.lib.webdemo.vo2.UserSuperBuilderVO.UserSuperBuilderVOBuilder, com.lib.webdemo.vo2.UserSuperBuilderVO$UserSuperBuilderVOBuilder, UserSuperBuilderVOBuilder, com.lib.webdemo.vo2.UserSuperBuilderVO$UserSuperBuilderVOBuilder, modifiers=1033
内部类: com.lib.webdemo.vo2.UserSuperBuilderVO.UserSuperBuilderVOBuilderImpl, com.lib.webdemo.vo2.UserSuperBuilderVO$UserSuperBuilderVOBuilderImpl, UserSuperBuilderVOBuilderImpl, com.lib.webdemo.vo2.UserSuperBuilderVO$UserSuperBuilderVOBuilderImpl, modifiers=26
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.UserSuperBuilderVO, 参数数量:1, modifiers=4
----
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=2
方法名称:toString, 参数数量:0, modifiers=1
方法名称:builder, 参数数量:0, modifiers=9


测试:class=class com.lib.webdemo.vo2.UserSuperBuilderVO$UserSuperBuilderVOBuilder
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.UserSuperBuilderVO$UserSuperBuilderVOBuilder, 参数数量: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=13
方法名称:name, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:id, 参数数量:1, modifiers=1
方法名称:tags, 参数数量:1, modifiers=1
方法名称:createTime, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1025
方法名称:build, 参数数量:0, modifiers=4161
方法名称:access$3, 参数数量:1, modifiers=4104
方法名称:access$5, 参数数量:1, modifiers=4104
方法名称:access$2, 参数数量:1, modifiers=4104
方法名称:access$4, 参数数量:1, modifiers=4104
方法名称:self, 参数数量:0, modifiers=4164
方法名称:self, 参数数量:0, modifiers=1028

UserSuperBuilderVO多了两个内部类,

UserSuperBuilderVOBuilder有13个方法,其中access$2~5(access$0~1 在 父类中),两个build,两个self。

 

创建子类对象,可以看到 父类的属性也在了:supId、supName

 

小结

@SuperBuilder 用在了 父类、子类上,可以成功创建父子类对象。

不过,这个功能属于试验性质的,暂无更多精时去探究。ben发布于博客园

 

4、父类用@Data、子类用@Builder(可行)

新建父类BaseData2VO、子类UserBuilder2VO:

// 1、BaseData2VO
import lombok.Data;

@Data
public class BaseData2VO {

	private Integer supId;
	private String supName;
	
}

// 2、UserBuilder2VO
import java.util.Date;
import java.util.List;

import lombok.Builder;
import lombok.ToString;

@Builder
@ToString(callSuper = true)
public class UserBuilder2VO extends BaseData2VO {

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

执行 子类UserBuilder2VO 的类分析:

测试:class=class com.lib.webdemo.vo2.UserBuilder2VO
prtClasses: length=1
内部类: com.lib.webdemo.vo2.UserBuilder2VO.UserBuilder2VOBuilder, com.lib.webdemo.vo2.UserBuilder2VO$UserBuilder2VOBuilder, UserBuilder2VOBuilder, com.lib.webdemo.vo2.UserBuilder2VO$UserBuilder2VOBuilder, modifiers=9
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo2.UserBuilder2VO, 参数数量: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=2
方法名称:toString, 参数数量:0, modifiers=1
方法名称:builder, 参数数量:0, modifiers=9

注意,这里的 UserBuilder2VOBuilder 不能执行上面的类分析,和单独使用 @Builder 注解类不同。ben发布于博客园

 

创建UserBuilder2VO对象:父类的属性需要使用 setter 方法设置

private static void testCreateDataBuilderVO() {
    cs.accept("\n\n测试:testCreateDataBuilderVO...");
    UserBuilder2VO user = UserBuilder2VO.builder()
        // 子
        .id(2)
        .name("sub2")
        .tags(new ArrayList<>())
        .createTime(new Date())
        .build();
    // 父
    user.setSupId(999);
    user.setSupName("super999");
    cs.accept("UserBuilder2VO user=" + user);
}

测试结果:

测试:testCreateDataBuilderVO...
UserBuilder2VO user=UserBuilder2VO(super=BaseData2VO(supId=999, supName=super999), id=2, name=sub2, tags=[], createTime=Fri Dec 02 20:38:49 CST 2022)

 

小结

可以用这种方式,只不过父类属性需要使用 setter方法设置。ben发布于博客园

 

参考资料

1、Lombok 中@Builder 的使用

https://www.cnblogs.com/minmin123/p/14368725.html

2、java Lombok下解决@Builder继承解决方法(@SuperBuilder)

http://www.manongjc.com/detail/28-quhwksxdbgivhva.html

 

ben发布于博客园

 

标签:02,modifiers,java,lib,探究,参数,lombok,com,class
From: https://www.cnblogs.com/luo630/p/16941903.html

相关文章

  • 【2022-11-26】今日计划
    20:00天地间惟谦谨是载福之道,骄则满,满则倾矣。凡动口动笔,厌人之俗,嫌人之鄙,议人之短,发人之覆,皆骄也。无论所指未必果当,即使一一切当,已为天道所不许。      ......
  • 【2022-11-27】裸婚动力
    20:00一切福田,不离方寸;从心而觅,感无不通。                                       ......
  • SequoiaDB分布式数据库2022.11月刊
    产品能力再获认可,入围多个榜单、报告 近日,由国际数据公司IDC主办的第七届数字化转型年度盛典在北京如期举行。本届盛会,主办方首次面向非企业客户群体(方案提供商)颁发I......
  • NOIP 2022 游记(题解)
    NOIP2022游记(题解)目录NOIP2022游记(题解)更好的阅读体验戳此进入T1[NOIP2022]种花题面SolutionCodeT2[NOIP2022]喵了个喵题面Solution写在后面CodeT3[NOIP2022]建......
  • Linux笔记02: Linux环境_2.1虚拟机软件VMware
     2.1虚拟机软件VMware如果直接在计算机上安装多个操作系统,同一个时刻只能运行一个操作系统,切换系统需重启计算机。VMware可以使用户在一台计算机上同时运行多个操......
  • eclipse使用lombok @Data注解仍然提示没有get/set方法
    在换了新电脑之后,安装好eclipse之后,测试了一下lombok插件,随便写了一个实体类之后,发现提示未使用。这时我就感觉应该是set/get方法没有正常生成的问题。在另一个类里调用App......
  • 2022-2023 20221403《计算机基础与程序设计》第十四周学习总结
    学期(2022-2023-1)学号(20221403)《计算机基础与程序设计》第十四周学习总结作业信息这个作业属于哪个课程<班级的链接>(如2022-2023-1-计算机基础与程序设计)这个......
  • Spring_day02
    本篇内容:Spring框架的IOC基于注解的方式Spring框架整合JUnit单元测试AOP的概述AOP的底层实现原理(了解)AOP功能基于AspectJ的配置文件方式注:案例中使用的都是Junit进行测试的,......
  • Mybatis_day02
    1.本篇总结:1、输入映射和输出映射a)输入参数映射b)返回值映射2、动态sqla)Ifb)Wherec)Foreachd)Sql片段3、关联查询a)一对一关联b)一对多关联4、Mybatis......
  • Week - 2022/10/24~2022/11/16 周记
    已经不知道多久没有写过周记了。。。。。。突然又想起来周记是因为cc0000提到了一下距离NOIP还有10天了,瞬间感觉好像可以开始写NOIP2022退役记了。。。所以先来......