Java中Lombok的@Data引发问题详解
引言
Lombok是一个Java库,可以自动为Java类生成一些标准的方法(如 equals()
, hashCode()
, toString()
等),以减少样板代码的编写。其中,@Data
是Lombok中一种常用的注解,作用是自动生成JavaBean中的getter/setter方法、hashCode/equals方法、toString方法、无参构造器等常用方法。
然而,@Data并不是万能的,其在使用时可能会有一些问题。
本文将详细讲解Java中Lombok的@Data引发的问题,并给出解决方案。
问题描述
问题1:内存溢出
考虑如下的的Java类:
@Data
public class MemoryLeak {
private String name;
private byte[] data;
public MemoryLeak(String name) {
this.name = name;
this.data = new byte[1024 * 1024 * 100]; // 100MB
}
}
该类中包含两个成员变量 name 和 byte[] data,其中 data 占用了较大的内存空间,长度为 100MB。
我们来测试一下:
public static void main(String[] args) {
List<MemoryLeak> list = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
MemoryLeak ml = new MemoryLeak("name " + i);
list.add(ml);
}
}
运行程序,会发现内存很快溢出。为什么呢?
这是因为,@Data注解生成的equals方法用到了contentEquals方法来判断两个字符串是否相等,contentEquals方法又会调用String类的subSequence方法,因此当两个字符串相等时,contentEquals方法会返回true,成为一个死循环。
一个可行的解决方案是在@EqualsAndHashCode注解中使用excludes属性排除掉那些可能引发问题的属性。
@Data
@EqualsAndHashCode(exclude = "data")
public class MemoryLeak {
private String name;
private byte[] data;
//...
}
问题2:参数校验不生效
现有一个Java类,使用@Data注解自动生成getter/setter方法,同时希望使用@NotNull注解来实现参数校验:
@Data
public class User {
@NotNull
private String name;
@NotNull
private String password;
//...
}
然而,当我们对该类进行参数校验时,会发现参数校验并没有生效:
public class UserService {
public void addUser(@Valid User user) {
// do something...
}
}
public class Test {
public static void main(String[] args) {
UserService userService = new UserService();
User user = new User();
userService.addUser(user);
}
}
但是,如果手动为该类生成setter/getter方法,并使用@NotNull注解来实现参数校验,那么参数校验就会生效了。
public class User {
private String name;
private String password;
public String getName() {
return name;
}
@NotNull
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
@NotNull
public void setPassword(String password) {
this.password = password;
}
}
为什么会出现这种情况呢?
因为@Data注解会覆盖掉手动定义的setter方法,所以参数校验不生效,解决方法是手动实现setter/getter方法来实现参数校验。
总结
@Data注解在自动生成代码时可以大幅减少代码量,提高开发效率,但也会引发一些问题,需要我们在实际开发中注意,避免出现问题。针对特定的问题,可以使用相应的注解属性或手动实现setter/getter方法来解决。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java中lombok的@Data引发问题详解 - Python技术站