lombok.xxx.callSuper不生效问题

前言

如果想要使用 lombok.config 全局配置 lombok.equalsAndHashCode.callSuper = call,建议 Lombok 版本至少升到 1.16.8[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tAeNHfv4-1658228942869)(C:\Users\riyou.jiang\AppData\Roaming\Typora\typora-user-images\image-20220719181047317.png)]

如果想要使用 lombok.config 全局配置 lombok.toString.callSuper = call,建议 Lombok 版本至少升到 1.18.6

在这里插入图片描述

具体可见:Lombok changelog

问题

现在多多少少都会使用 Lombok,暂且不提其给代码带来的可读性、可维护性问题。

单从使用场景上,受限于工具本身,在带来便捷性同时,愈发"懒惰"就会希望有更高的便捷性。

就今天主题而言,EqualsAndHashCode@ToString@Data@Value 包含对应功能的注解,在有继承不仅 Object时,默认只考虑到自身类,不会包含父类。

@Data
public class User {
    
    
    private Long userId;
    
    @Data
    public static class ExtendUser extends User {
    
    
        private String name;
    }
}
public static void test() {
    
    
    ExtendUser user1 = new ExtendUser();
    user1.setUserId(1L);
    user1.setName("name");
    ExtendUser user2 = new ExtendUser();
    user2.setUserId(2L);
    user2.setName("name");
    System.out.println("hashEqRes=" + (user1.hashCode()==user2.hashCode()));
    System.out.println("eqRes=" + user1.equals(user2));
    System.out.println(user1);
}

输出结果:

hashEqRes=true
eqRes=true
User.ExtendUser(name=name)

可以看到无论是 equal()hashCode()toString()都只考虑到当前类,而没有向上包含 User类。

如果想要解决这个问题,一般方式是两个

  • 注解加上 callSuper = true
  • lombok.config 文件加上全局 callSuper 配置。

注解方法

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static class ExtendUser extends User

可以看到,由于 @Data注解不支持 callSuper 参数,所以即使在使用了 @Data注解,也依然需要显式使用@ToString@EqualsAndHashCode

看一下效果:

hashEqRes=false
eqRes=false
User.ExtendUser(super=User(userId=1), name=name)

确实可以解决相关生成方法不包含父类字段的问题,但缺点就是

  • 一是需要在使用便捷注解的同时,再单独使用功能注解;
  • 二是在大量类需要包含父类时,需要重复工作,浪费时间。

所以,为了解决这个问题,Lombok 在 1.16.8 和 1.18.6 分别引入了全局配置 @ToString@EqualsAndHashCode 的方式。

全局配置方式

注意:版本一定要支持配置!!!!

全局配置是通过 lombok.config 文件来指定配置,该文件可以放在项目根目录下即可生效。

# 全局设置@EqualsAndHashCode的callSuper属性为true
lombok.equalsAndHashCode.callSuper = call
# 全局设置@ToString的callSuper属性为true
lombok.toString.callSuper = call

注意,这两个的有效值是call/skip/warn

  • skip 是不包含父类字段;
  • warn是不包含父类字段,但会在编译时产生一条告警;
    • PS:@EqualsAndHashCode如果是 warn,idea 会在代码上产生一个提示;而@ToString不会。
    • Lombok 插件已经是最新的,可能是 Idea 版本不支持(2019.3)。
  • call即是想要的,包含父类字段。

注意,在默认值,两者是不同的:@ToString 的默认值是 skip@EqualsAndHashCode的是warn

warn 下呈现的结果:

在这里插入图片描述

call下,呈现的结果:

hashEqRes=false
eqRes=false
User.ExtendUser(super=User(userId=1), name=name)

如何查看当前版本是否支持某个全局配置

之前全局加了lombok.toString.callSuper = call,就放心了,也没有关注是否生效;

结果,过了半年调试时,突然瞥见 ToString打印并不会包含父类,这才追根究底还是版本不支持。

可以通过 lombok.ConfigurationKeys,查看当前版本支持哪些配置的 key。

在这里插入图片描述

可以通过 github 或文章开始的 changelog 来找哪些版本支持。

猜你喜欢

转载自blog.csdn.net/jiangxiayouyu/article/details/125878833