程序员

lombok在继承类上的使用

2020-12-07  本文已影响0人  Lyudmilalala

在普通的Java程序里,父类引用指向子类对象时,该引用只能调用父类中定义的方法和变量

例如为HTTP请求创建一个基类CommonResponse

public class CommonResponse {
    protected int status;
    protected String msg;
    
    public CommonResponse() {
        this.status = HttpStatus.OK.value();
        this.msg = "Success";
    }
    
    public CommonResponse(int status, String msg) {
        this.status = status;
        this.msg = msg;
    }
    
    public String getFileOriName() {
        return "I don't have a filename";
    }   
}

再创建一个子类FileUploadResponse

public class FileUploadResponse extends CommonResponse {

    private String fileOriName;
    private String filePath;
    
    public FileUploadResponse (String oriName, String filePath) {
        super();
        fileOriName = oriName;
        this.filePath = filePath;
    }
    
    public FileUploadResponse(int status, String msg) {
        super(status, msg);
    }
    
    public String getFileOriName() {
        return fileOriName;
    }

        public String getFilePath() {
        return filePath;
    }
}

Test Case

    /*
     * Parent class - CommonResponse
     * Child class - FileUploadResponse
     */
    @Test
    public void lombokTest() throws JsonProcessingException {
        CommonResponse fileUploadResponse1 = new FileUploadResponse("file1.txt", "/Users/file1.txt");
        System.out.println(fileUploadResponse1.getMsg());
        System.out.println(fileUploadResponse1.getFileOriName());
    }

结果

Success
file1.txt

首先,getFilePath()的方法是不存在于这个对象上的
getFileOriName()通过重写成功调用了父类中不存在的变量

这个时候如果用jackson将对象转换为json string,转换成的对象会因为get方法的不同而有所不同,如果父类和子类都不写getter,则jackson会报错。

而如果写了getMsg()getFileOriName(),返回的对象则会为msgfileOriName的组合。

{"msg":"Success","fileOriName":"I don't have a filename"}
{"msg":"Success","fileOriName":"file1.txt"}

为父类和子类对象都加上Lombok的@Data标签后,发现子类对父类的重写都依然存在

修改父类

@Data
public class CommonResponse {
    protected int status;
    protected String msg;
    
    public CommonResponse() {
        this.status = HttpStatus.OK.value();
        this.msg = "Success";
    }
    
    public CommonResponse(int status, String msg) {
        this.status = status;
        this.msg = msg;
    }
        
    public String getFileOriName() {
        return "I don't have a filename";
    }
    
}

修改子类

@Data
public class FileUploadResponse extends CommonResponse {

    private String fileOriName;
    private String filePath;
    
    public FileUploadResponse (String oriName, String filePath) {
        super();
        fileOriName = oriName;
        this.filePath = filePath;
    }
    
    public FileUploadResponse(int status, String msg) {
        super(status, msg);
    }

}

Test Case

    /*
     * Parent class - CommonResponse
     * Child class - FileUploadResponse
     */
    @Test
    public void lombokTest() throws JsonProcessingException {
        CommonResponse fileUploadResponse1 = new FileUploadResponse("file1.txt", "/Users/file1.txt");
        System.out.println(fileUploadResponse1.getMsg());
        System.out.println(fileUploadResponse1.getFileOriName());
    }

结果

Success
file1.txt

我们可以注意到另一件事情,在Lombok默认的@ToString方法里,是不带父类变量的
Test Case

    /*
     * Parent class - CommonResponse
     * Child class - FileUploadResponse
     */
    @Test
    public void lombokTest() throws JsonProcessingException {
        CommonResponse commonResponse = new CommonResponse();
        CommonResponse fileUploadResponse1 = new FileUploadResponse("file1.txt", "/Users/file1.txt");
        System.out.println(commonResponse);
        System.out.println(fileUploadResponse1);
    }

结果

CommonResponse(status=200, msg=Success)
FileUploadResponse(fileOriName=file1.txt, filePath=/Users/file1.txt)

但如果使用Jackson将对象转化为json string,子类继承父类的变量也会全部被打印出来
Test Case

    /*
     * Parent class - CommonResponse
     * Child class - FileUploadResponse
     */
    @Test
    public void lombokTest() throws JsonProcessingException {
        CommonResponse commonResponse = new CommonResponse();
        CommonResponse fileUploadResponse1 = new FileUploadResponse("file1.txt", "/Users/file1.txt");
        System.out.println(commonResponse);
        System.out.println(fileUploadResponse1);
        System.out.println(JsonConverter.objToJson(commonResponse));
        System.out.println(JsonConverter.objToJson(fileUploadResponse1));
    }

        /*
     * 002.对象转换成json
     * @param:传入对象
     * @return:json字符串
     */
    public static String objToJson(Object obj) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(obj);
    }

结果

CommonResponse(status=200, msg=Success)
FileUploadResponse(fileOriName=file1.txt, filePath=/Users/file1.txt)
{"status":200,"msg":"Success","fileOriName":"I don't have a filename"}
{"status":200,"msg":"Success","fileOriName":"file1.txt","filePath":"/Users/file1.txt"}

如果想要在@ToString时打印父类变量,或者在比较时使用父类变量,则需要加上callSuper = true的注释
修改子类

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper=true)
public class FileUploadResponse extends CommonResponse {

    private String fileOriName;
    private String filePath;
    
    public FileUploadResponse (String oriName, String filePath) {
        super();
        fileOriName = oriName;
        this.filePath = filePath;
    }
    
    public FileUploadResponse(int status, String msg) {
        super(status, msg);
    }

}

重跑Test结果

CommonResponse(status=200, msg=Success)
FileUploadResponse(super=CommonResponse(status=200, msg=Success), fileOriName=file1.txt, filePath=/Users/file1.txt)
{"status":200,"msg":"Success","fileOriName":"I don't have a filename"}
{"status":200,"msg":"Success","fileOriName":"file1.txt","filePath":"/Users/file1.txt"}

References
父类引用指向子类对象

搜索资料过程中发现的有用的避雷贴
Lombok插件安装与使用说明
浅析JavaBean继承后重写父类属性和lombok注解带来的问题和解决方案

上一篇 下一篇

猜你喜欢

热点阅读