详解@Data注解
@Data 是 Lombok提供的注解,不是Java标准库的。
给类加上@Data后,会自动生成以下方法:
- 所有字段的 getter / setter
- toString()
- equals() / hashCode()
- 构造器(部分情况)
1.getter/setter
总结 getter/setter 的作用:
getter | 读取字段值(封装后安全访问) |
setter | 修改字段值(可以加校验逻辑) |
Lombok 的好处 | 省去重复写这些模板代码 |
2.toString()
✅ 一、什么是toString()方法?
- toString()是Java所有类默认继承的方法,定义在Object类中:
public String toString()
- 它的作用是返回当前对象的字符串表示,比如你打印一个对象:
System.out.println(myObj);
其实底层会自动调用:
System.out.println(myObj.toString());
😵 默认的toString()很难用!
来看一个没重写过的toString()效果:
Person p = new Person(); System.out.println(p);
输出是这样的:
Person@6f2b958e
- Person 是类名
- @6f2b958e 是对象在内存里的地址哈希
- ❌ 你完全看不出这个对象的内容!
✅ @Data自动生成的toString()就很强!
假设你有个类:
@Data public class Person { private String name; private int age; }
Lombok自动帮你生成的toString()方法类似这样:
@Override public String toString() { return "Person(name=" + this.name + ", age=" + this.age + ")"; }
然后你执行:
Person p = new Person(); p.setName("Tom"); p.setAge(25); System.out.println(p);
✅ 控制台输出:
Person(name=Tom, age=25)
是不是一目了然!这就是 Lombok 给你带来的好处!
✅ 总结:@Data里的toString()是干什么的?
默认版本 | 打印的是内存地址,看不懂 |
@Data版 | 自动生成显示所有字段和字段值 |
使用场景 | 打日志、调试对象内容、快速了解对象状态 |
好处 | 无需手写代码,输出更清晰,方便开发 |
✅ 扩展:我能控制toString()显示哪些字段吗?
可以的,用Lombok的@ToString(exclude = {"password"})这样:
@ToString(exclude = "password") public class User { private String username; private String password; }
输出时就不会显示密码啦。
3.equals() / hashCode()
✅ 一、equals()是干什么的?
📌 它是Java中的一个方法,用来判断两个对象"值上是否相等":
public boolean equals(Object obj)
🧠 默认行为(没重写的情况下):
Person p1 = new Person("Tom", 20); Person p2 = new Person("Tom", 20); System.out.println(p1.equals(p2)); // false❌,因为默认是比较内存地址
👉 默认的equals()是这样的:
public boolean equals(Object obj) { return this == obj; // 只比较是不是同一个对象 }
✅ 二、@Data自动生成的equals()是什么样?
它会帮你根据字段值来判断对象是否相等,比如:
@Data public class Person { private String name; private int age; }
等同于你手写的:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); }
✅ 有了这个之后:
Person p1 = new Person("Tom", 20); Person p2 = new Person("Tom", 20); System.out.println(p1.equals(p2)); // true✅
但是关于hashCode()这块我也没太研究明白,可能用的也不多,后面待补充吧。
4.构造器
注意一个重要误区:@Data所默认自带的是一个类默认的无参构造器(构造方法),而绝对不是帮你new了一个新的实例。
✅ @Data自动生成了什么构造器?
严格来说,@Data本身只保证:
- 自动生成无参构造器(如果你没有定义的话)
但如果你还加上了@AllArgsConstructor、@RequiredArgsConstructor 等注解,就能自动生成带参数的构造器了。
✅ 如果你只加@Data,它默认只生成无参构造器。
✅ 举个例子:
@Data public class Person { private String name; private int age; }
编译后相当于:
public class Person { private String name; private int age; public Person() {} // 自动生成的无参构造器 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person(name=" + name + ", age=" + age + ")"; } }