我Lombok 主要注解详解及代码示例
Lombok 是一个 Java 库,通过注解在编译时生成常用样板代码,如构造方法、getter/setter、toString等,减少代码冗余,提升开发效率。本文详细介绍 Lombok 的主要注解并附代码示例。
1. @Data
作用:等价于@ToString、@EqualsAndHashCode、@Getter、@Setter、@RequiredArgsConstructor的组合,为类生成必要参数构造方法、getter、setter、toString、equals和hashcode方法。示例:
package org.example;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
private String name;
private int age;
private final String id; // final字段
public static void main(String[] args) {
User user = new User("Alice", 30, "123");
System.out.println(user.getName()); // 调用getter
user.setName("Bob"); // 调用setter
System.out.println(user); // 调用toString
}
}
final字段能否生成对应的方法
在使用 Lombok 的 @Data 注解时,private final String id; 字段可以生成对应的方法,但具有一定特殊性,下面为你详细分析:
生成的方法情况
getter 方法:@Data 注解包含 @Getter,因此会为 id 字段生成 getter 方法。你可以在代码中通过 user.getId() 来获取 id 字段的值。setter 方法:由于 id 被 final 修饰,意味着它一旦被赋值就不能再改变,所以 @Data 不会为 final 修饰的字段生成 setter 方法。如果你尝试调用 user.setId("newId") ,代码将无法编译。构造方法:@Data 包含 @RequiredArgsConstructor,它会生成一个包含所有被 final 修饰的实例变量的构造方法。所以在创建 User 对象时,必须为 id 字段提供值,就像示例代码中的 User user = new User("Alice", 30, "123"); 。toString、equals 和 hashCode 方法:@Data 注解包含 @ToString 和 @EqualsAndHashCode,这些注解会在生成的 toString、equals 和 hashCode 方法中考虑 id 字段。也就是说,id 字段会参与对象的字符串表示、相等性比较和哈希码计算。
代码示例验证
下面是一段验证代码,展示了上述方法的使用情况:
import lombok.Data;
@Data
public class User {
private String name;
private int age;
private final String id; // final字段
public static void main(String[] args) {
User user = new User("Alice", 30, "123");
// 调用 id 的 getter 方法
System.out.println("User ID: " + user.getId());
// 调用 name 的 getter 方法
System.out.println("User Name: " + user.getName());
// 调用 name 的 setter 方法
user.setName("Bob");
System.out.println("Updated User Name: " + user.getName());
// 尝试调用 id 的 setter 方法,这行代码会编译错误
// user.setId("456");
// 调用 toString 方法
System.out.println("User Info: " + user);
User anotherUser = new User("Bob", 30, "123");
// 调用 equals 方法
System.out.println("Are users equal? " + user.equals(anotherUser));
// 调用 hashCode 方法
System.out.println("User hash code: " + user.hashCode());
}
}
总结
@Data 注解会为 final 字段生成 getter 方法,并且该字段会参与 toString、equals 和 hashCode 方法的生成,但不会为其生成 setter 方法。在创建对象时,必须为 final 字段提供初始值。
2. @Getter / @Setter
作用:分别生成getter和setter方法,可作用于类或字段。示例:
package org.example;
import lombok.Getter;
import lombok.Setter;
// 使用 @Getter 和 @Setter 注解
@Getter
@Setter
public class Student {
// 学生姓名
private String name;
// 学生年龄
private int age;
// 学生所在班级
private String className;
public static void main(String[] args) {
// 创建一个 Student 对象
Student student = new Student();
// 使用自动生成的 setter 方法设置学生信息
student.setName("John");
student.setAge(18);
student.setClassName("Class 10");
// 使用自动生成的 getter 方法获取学生信息并输出
System.out.println("Student Name: " + student.getName());
System.out.println("Student Age: " + student.getAge());
System.out.println("Student Class: " + student.getClassName());
}
}
3. @NoArgsConstructor
作用:生成无参构造方法。示例:
import lombok.NoArgsConstructor;
// 使用 @NoArgsConstructor 注解为类生成无参构造函数
@NoArgsConstructor
public class Car {
// 汽车品牌
private String brand;
// 汽车颜色
private String color;
// 汽车价格
private double price;
public static void main(String[] args) {
// 创建一个 Car 对象,调用无参构造函数
Car car = new Car();
// 这里可以添加后续对 car 对象的操作,例如设置属性值、打印信息等
System.out.println("A car object has been created.");
}
}
4. @AllArgsConstructor
作用:生成包含所有实例变量的构造器。示例:
import lombok.AllArgsConstructor;
@AllArgsConstructor
class Employee {
private String name;
private int age;
private String department;
private double salary;
public static void main(String[] args) {
Employee employee = new Employee("Alice", 28, "HR", 5000.0);
System.out.println("Employee created: " + employee.name);
}
}
5. @RequiredArgsConstructor
@RequiredArgsConstructor 是 Lombok 库提供的一个注解,其主要功能是根据类中被 final 修饰的实例变量自动生成相应的构造方法。具体规则如下:
存在 final 变量:当类中存在被 final 修饰的实例变量时,Lombok 会生成一个包含所有 final 变量作为参数的构造方法。因为 final 变量一旦被赋值就不能再改变,所以在创建对象时必须对其进行初始化,这个构造方法就是为了满足这一需求。不存在 final 变量:若类中没有 final 修饰的实例变量,Lombok 会生成一个无参构造方法。
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class Book {
private final String isbn;
private String title;
private double price;
public static void main(String[] args) {
// 创建 Book 对象,需要传入 final 字段 isbn 的值
Book book = new Book("978-3-16-148410-0");
// 后续可以使用 setter 方法设置其他非 final 字段的值
book.title = "Effective Java";
book.price = 49.99;
System.out.println("Book ISBN: " + book.isbn);
System.out.println("Book Title: " + book.title);
System.out.println("Book Price: " + book.price);
}
}
6. @ToString / @EqualsAndHashCode
作用:生成toString和equals/hashCode方法,exclude属性可定制。示例:
import lombok.ToString;
import lombok.EqualsAndHashCode;
// 在生成的 toString 方法中排除 releaseDate 字段
@ToString(exclude = "releaseDate")
// 在生成的 equals 和 hashCode 方法中排除 director 字段
@EqualsAndHashCode(exclude = "director")
public class Movie {
// 电影的标题
private String title;
// 电影的导演
private String director;
// 电影的上映日期
private String releaseDate;
// 构造方法,用于初始化电影对象的各个属性
public Movie(String title, String director, String releaseDate) {
this.title = title;
this.director = director;
this.releaseDate = releaseDate;
}
public static void main(String[] args) {
// 创建第一个电影对象,电影名为《盗梦空间》,导演是克里斯托弗·诺兰,上映日期为 2010 年 7 月 16 日
Movie movie1 = new Movie("盗梦空间", "克里斯托弗·诺兰", "2010-07-16");
// 创建第二个电影对象,电影名同样为《盗梦空间》,但导演设为其他人,上映日期为 2010 年 7 月 16 日
Movie movie2 = new Movie("盗梦空间", "其他人", "2010-07-16");
// 调用 movie1 的 toString 方法,输出结果不包含 releaseDate 字段
System.out.println(movie1.toString());
// 比较 movie1 和 movie2 是否相等,比较时会忽略 director 字段
System.out.println(movie1.equals(movie2));
}
}
