如果想要使用 lombok.config
全局配置 lombok.equalsAndHashCode.callSuper = call
,建议 Lombok 版本至少升到 1.16.8。
如果想要使用 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
类。
如果想要解决这个问题,一般方式是两个
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
是不包含父类字段,但会在编译时产生一条告警;
@EqualsAndHashCode
如果是 warn,idea 会在代码上产生一个提示;而@ToString
不会。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 来找哪些版本支持。