美文网首页程序员
lombok在继承类上的使用

lombok在继承类上的使用

作者: Lyudmilalala | 来源:发表于2020-12-07 01:03 被阅读0次

    在普通的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注解带来的问题和解决方案

    相关文章

      网友评论

        本文标题:lombok在继承类上的使用

        本文链接:https://www.haomeiwen.com/subject/xuxzwktx.html