实体类继承某类后覆盖重写toString方法无法打印所有的实体

发生缘由

  • SpringBoot项目

运行环境

  • 电脑系统:win10
  • jdk版本:jdk-8
  • SpringBoot版本:v2.7.13
  • MP版本:3.5.3
<dependency>
    <groupId>org.projectlombokgroupId>
    <artifactId>lombokartifactId>
    
    <version>1.18.12version>
    
    <scope>providedscope>
dependency>

项目模拟

/**
 * Emp实体类
 *  1.Data注解:包含了Setter、Getter、ToString、EqualsAndHashCode等注解
 *  2.NoArgsConstructor注解:无参构造函数注解
 *  3.AllArgsConstructor注解:全参构造函数注解
 *  4.Accessors(chain = true):给set方法开启链式编程调用
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Emp {
    private Integer eid;
    private String empName;
    private Integer age;
    private Character sex;
    private String email;
    private Integer did;
    private Integer version;
}
@Data
@Accessors(chain = true)
public class Dept {
    private Integer did;
    private String deptName;
}
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class EmpDto extends Emp {
    private Dept dept;
}
@Test
public void testEmpDtoToString() {
    // 创建Dept实体类
    Dept dept = new Dept();
    dept.setDid(1).setDeptName("A");
    // 创建EmpDto数据传输类
    EmpDto empDto = new EmpDto();
    empDto.setDept(dept);
    empDto.setEid(1).setDid(1).setEmail("[email protected]").setSex('男').setAge(21).setVersion(1);
    // 调用toString方法打印empDto可是发现打印结果为:EmpDto(dept=Dept(did=1, deptName=A))
    System.out.println(empDto);
}

可以发现打印结果并非是我们想要的EmpDto{dept=Dept(did=1, deptName=A), eid=1, empName='null', age=21, sex=男, email='[email protected]', did=1, version=1},而是EmpDto(dept=Dept(did=1, deptName=A)),所有从Emp实体类继承来的属性都没有打印值。

解决方案

出现该问题的原因主要是访问修饰符的问题,我们给 Emp 实体类中的所有属性设置的访问修饰都是 private,这导致了 EmpDao 数据传输类并没有办法继承这些属性,也就导致了无法打印值了。

所以究其根本就是现在 EmpDao 类里面并没有继承下来 Emp 实体类中的属性,直到原因,那么就可以来解决了。对此,一共有两种方法:调用 getter 方法、修改访问修饰符。

调用 getter 方法

既然没有该属性,那么我们可以调用该属性的 getter 方法来获取值。

@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class EmpDto extends Emp {
    private Dept dept;

    @Override
    public String toString() {
        return "EmpDto{" +
                "dept=" + dept +
                ", eid=" + getEid() +
                ", empName='" + getEmpName() + '\'' +
                ", age=" + getAge() +
                ", sex=" + getSex() +
                ", email='" + getEmail() + '\'' +
                ", did=" + getDid() +
                ", version=" + getVersion() +
                '}';
    }
}

修改访问修饰符

既然是 private 访问修饰符导致这些属性无法被继承,那么换一种即可!

修饰符 当前类 同一包内 子孙类(同一包) 子孙类(不同包) 其他包
public Y Y Y Y Y
protected Y Y Y Y/N N
default Y Y Y N N
private Y N N N N

这里换成 protected 来修饰

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Emp {
    protected Integer eid;
    protected String empName;
    protected Integer age;
    protected Character sex;
    protected String email;
    protected Integer did;
    protected Integer version;
}

只操作这一步发现还是不可以的,这是因为@Data生成的toString()方法默认并不会打印父类中的属性,所以这里需要我们手动生成一下toString()

@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class EmpDto extends Emp {
    private Dept dept;

    // IDEA快捷键:Alt + Ins,然后选择toString(),最后选择所有的属性即可
    @Override
    public String toString() {
        return "EmpDto{" +
                "dept=" + dept +
                ", eid=" + eid +
                ", empName='" + empName + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", email='" + email + '\'' +
                ", did=" + did +
                ", version=" + version +
                '}';
    }
}

你可能感兴趣的:(Java基础,java,开发语言)