@Builder
@Getter
class Student implements {
private String num;
private String name;
private String address = "default";
}
public class TestExample {
public static void main(String[] args) {
Student student = Student.builder().name("Student").num("123").build();
System.out.println(JSON.toJSONString(student));
}
}
{"name":"Student","num":"123"}
class Student {
private String num;
private String name;
private String address = "default";
Student(String num, String name, String address) {
this.num = num;
this.name = name;
this.address = address;
}
// 生成的 StudentBuilder 对象把我们的默认值丢失了
public static StudentBuilder builder() {
return new StudentBuilder();
}
public String getNum() {
return this.num;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public static class StudentBuilder {
private String num;
private String name;
private String address;
StudentBuilder() {
}
public StudentBuilder num(String num) {
this.num = num;
return this;
}
public StudentBuilder name(String name) {
this.name = name;
return this;
}
public StudentBuilder address(String address) {
this.address = address;
return this;
}
public Student build() {
return new Student(this.num, this.name, this.address);
}
public String toString() {
return "Student.StudentBuilder(num=" + this.num + ", name=" + this.name + ", address=" + this.address + ")";
}
}
}
@Builder
@Getter
class Student {
private String num;
private String name;
@Builder.Default
private String address = "default";
}
public class TestExample {
public static void main(String[] args) {
Student student = Student.builder().name("Student").num("123").build();
System.out.println(JSON.toJSONString(student));
}
}
{"address":"default","name":"Student","num":"123"}
// 来看看 @Builder.Default 是怎么实现的:
class Student {
private String num;
private String name;
private String address;
private static String $default$address() {
return "default";
}
Student(String num, String name, String address) {
this.num = num;
this.name = name;
this.address = address;
}
public static StudentBuilder builder() {
return new StudentBuilder();
}
public String getNum() {
return this.num;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public static class StudentBuilder {
private String num;
private String name;
private boolean address$set;
private String address$value;
StudentBuilder() {
}
public StudentBuilder num(String num) {
this.num = num;
return this;
}
public StudentBuilder name(String name) {
this.name = name;
return this;
}
public StudentBuilder address(String address) {
this.address$value = address;
this.address$set = true;
return this;
}
public Student build() {
String address$value = this.address$value;
// 如果没有设置该属性则使用默认值
if (!this.address$set) {
address$value = Student.$default$address();
}
return new Student(this.num, this.name, address$value);
}
public String toString() {
return "Student.StudentBuilder(num=" + this.num + ", name=" + this.name + ", address$value=" + this.address$value + ")";
}
}
}
补充一点:很多人 喜欢 @Builder 和 @Data 搭配使用,包括我自己哈哈哈,这样会导致生成的构造器是可变的,这违反了构造器原理的,构造器应该是不可变的。
因此建议 @Builder 使用在一些不可变的对象中。
- 继承关系时,子类需要使用 @SuperBuilder
- 设置默认值需要使用 @Builder.Default
@Data
class Student {
/**
* 设置为 final 构造必填
*/
private final String num;
/**
* 设置为 final 构造必填
*/
private final String name;
private int age;
private String address = "default";
Student(String num, String name) {
this.num = num;
this.name = name;
}
}
public class TestExample {
public static void main(String[] args) {
Student student = new Student("123", "小明");
student.setAge(12);
System.out.println(student);
}
}
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Accessors {
// 与chain=true类似,区别在于getter和setter不带set和get前缀
boolean fluent() default false;
// 设置chain=true,生成setter方法返回对象,代替了默认的返回void
boolean chain() default false;
// set、get方法忽略指定的前缀(驼峰式)
// 注:必须所有字段都有前缀
String[] prefix() default {};
}
// fluent = true 日常开发中我们一般使用这个配置就行
@Data
@Accessors(fluent = true)
class Student {
/**
* 设置为 final 构造必填
*/
private final String num;
/**
* 设置为 final 构造必填
*/
private final String name;
private int age;
private String address = "default";
public Student(String num, String name) {
this.num = num;
this.name = name;
}
}
public class TestExample {
public static void main(String[] args) {
Student student = new Student("123", "小明").age(1).address("北京");
System.out.println(JSON.toJSONString(student));
}
}
{"address":"北京","age":1,"name":"小明","num":"123"}
// chain = true
@Data
@Accessors(chain = true)
class Student {
/**
* 设置为 final 构造必填
*/
private final String num;
/**
* 设置为 final 构造必填
*/
private final String name;
private int age;
private String address = "default";
public Student(String num, String name) {
this.num = num;
this.name = name;
}
}
public class TestExample {
public static void main(String[] args) {
Student student = new Student("123", "小明").setAge(1);
System.out.println(JSON.toJSONString(student));
}
}
{"address":"default","age":1,"name":"小明","num":"123"}
// prefix = "prefix"
@Data
@Accessors(chain = true,prefix = "prefix")
class Student {
/**
* 设置为 final 构造必填
*/
private final String prefixNum;
/**
* 设置为 final 构造必填
*/
private final String prefixName;
private int prefixAge;
private String prefixAddress = "default";
public Student(String prefixNum, String prefixName) {
this.prefixNum = prefixNum;
this.prefixName = prefixName;
}
}
public class TestExample {
public static void main(String[] args) {
Student student = new Student("123", "小明").setAge(1).setAddress("北京");
System.out.println(JSON.toJSONString(student));
}
}
{"address":"北京","age":1,"name":"小明","num":"123"}
class Student {
private final String prefixNum;
private final String prefixName;
private int prefixAge;
private String prefixAddress = "default";
public Student(String prefixNum, String prefixName) {
this.prefixNum = prefixNum;
this.prefixName = prefixName;
}
public String getNum() {
return this.prefixNum;
}
public String getName() {
return this.prefixName;
}
public int getAge() {
return this.prefixAge;
}
public String getAddress() {
return this.prefixAddress;
}
public Student setAge(int prefixAge) {
this.prefixAge = prefixAge;
return this;
}
public Student setAddress(String prefixAddress) {
this.prefixAddress = prefixAddress;
return this;
}
// 省略一些其他方法
}
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。
🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。
💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。
🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。
📖 保持关注我的博客,让我们共同追求技术卓越。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。