前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java避坑指南:慎用Lombok 代码自动生成工具

Java避坑指南:慎用Lombok 代码自动生成工具

作者头像
崔认知
发布2023-06-20 11:05:31
3240
发布2023-06-20 11:05:31
举报
文章被收录于专栏:nobodynobody

简介


Lombok在java开发者当中作为比较知名的自动代码生成工具,经常用来自动生成set方法、get方法、equals 方法、 hashCode 方法、构造函数方法、log变量生成等。

核心原理是在java编译期间扩展注解处理器:

代码语言:javascript
复制
javax.annotation.processing.AbstractProcessor

自动生成相关代码。

https://github.com/projectlombok/lombok/blob/master/src/core/lombok/core/AnnotationProcessor.java

但是自动生成的逻辑也会让我们在开发中踩坑。

代码语言:javascript
复制
坑:@ToString注解带来的

1、导致StackOverflowError 异常;

像树之类的数据结构:

代码语言:javascript
复制
   @ToString
    @Setter
    @Getter
    public static class Node {
        private Object vale;
        private Node left;
        private Node parent;
        private Node right;
    }

就存在循环引用,最终导致栈溢出异常。

当然你可以使用

代码语言:javascript
复制
@ToString(exclude = "parent")

解决,不过我们必须时刻记着配置,影响我们的开发注意力。

2、在Hibernate 实体中,如果属性带有注解FetchType.LAZY,就会导致懒加载失效,导致性能问题;

坑:使用@AllArgsConstructor,而未使用@NoArgsConstructor


使用了@AllArgsConstructor,就会导致java编译器,不再生成默认构造函数,在一些反序列框架中,如果没有默认构造函数,就会导致反序列化失败。

坑:@EqualsAndHashCode导致Hash容器寻不到数据


默认情况下,非static、非transient 的字段用来参与equals、hashCode方法的实现,对于Hash容器,如果这两个方法的实现随着属性字段的修改,会导致找不到元素值的现象。

示例:

代码语言:javascript
复制
package com.example.demo;


import lombok.*;

import java.util.HashMap;
import java.util.Map;


/**
 * @author 认知科技技术团队
 * 微信公众号:认知科技技术团队
 */
public class Demo {
    public static void main(String[] args) throws ReflectiveOperationException {
        Map<Node,Node> map = new HashMap();
        Node node = new Node();
        node.setVale("who");
        map.put(node,node);

        Node node1 = map.get(node);
        System.out.println(node1);

        node.setVale("are");
        node1 = map.get(node);
        System.out.println(node1);
    }

    @Setter
    @Getter
    @EqualsAndHashCode
    @ToString
    public static class Node {
        private Object vale;
    }

}

运行结果:

坑:@Setter、@Getter注解导致的序列化坑:第一个字母小写,第二个字母大写的属性生成的get-set方法,与idea,Mybatis,Java官方认可的生成的不一样,导致字段序列化失败


示例:

代码语言:javascript
复制
 @Setter
    @Getter
    @EqualsAndHashCode
    @ToString
    public static class Node {
        private Object nName;
    }

看一下生成的字节码反编译的效果:

我们对比下idea,Mybatis,Java官方认可的生成的方法:

Lombok@Setter、@Getter注解对于第一个字母小写,第二个字母大写的属性生成的get-set方法,与idea,Mybatis,Java官方认可的生成的方法是不相同的,主要区别在于第一个字母是小写还是大写。这样就会导致一些序列化问题,比如mybatis框架就不能把此类字段的值序列化到数据库。

小结


Lombok自动生成代码工具虽然避免了冗余和样板代码,让我们的类看着整洁,但是也造成了一些问题,上述只列出了项目中常见的,还有许多坑点,在此不再一一列举。

如果要使用Lombok,我们最好验证一下自动生成的代码(反编译字节码),是不是符合我们的需求。

我们的项目规范:一律禁止使用Lombok工具,使用IDE自动生成。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档