基础
链式编程定义:链式编程的原理就是返回一个 this 对象,就是返回本身,达到链式效果
public class User {private Integer id;private String name;private Integer age;public User setId(Integer id) {this.id = id;return this;}public User setName(String name) {this.name = name;return this;}public User setAge(Integer age) {this.age = age;return this;}}
StringBuilder 就使用了链式编程的写法:
// StringBuilder的append方法的源码@Overridepublic StringBuilder append(String str) {super.append(str);return this;}// StringBuilder的append方法使用StringBuilder builder = new StringBuilder();builder.append("Hello").append("\t").append("world!");
lombok中使用链式编程
在 pom.xml 文件中引入 lombok 依赖:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.14</version><scope>provided</scope></dependency>
lombok 实现链式编程:在 bean 上添加 @Accessors(chain = true)
@Data@Accessors(chain = true)public class User implements Serializable {private static final long serialVersionUID = -1602774207630314992L;private Integer id;private String username;private String password;}
静态链式编程
静态的链式编程比普通的链式编程的好处:
- 创建对象更简单
- 可以在静态方法、静态代码块等中使用
- 对于必输字段,可以强制要求
屏蔽 class 的 new,只能通过静态方法创建新实例,如:
public class User {private Integer id;private String name;private Integer age;// 静态构造方法,避免外部调用private User(){}// 对外提供的创建对象的方法public static User of(){return new User();}public User setId(Integer id) {this.id = id;return this;}public User setName(String name) {this.name = name;return this;}public User setAge(Integer age) {this.age = age;return this;}}
在创建 bean 时,存在一些必输字段,静态的链式编程可以声明这些必输字段:
public class User {private Integer id;private String name;private Integer age;// 静态构造方法,避免外部调用private User(){}// 对外提供的创建对象的方法public static User of(String name){if (name == null) {throw new NullPointerException("name is marked non-null but is null");} else {this.name = name;}}public User setId(Integer id) {this.id = id;return this;}public User setName(String name) {this.name = name;return this;}public User setAge(Integer age) {this.age = age;return this;}}
lombok 使用静态链式编程
在 bean 上添加 @RequiredArgsConstructor(staticName = “of”) 注解就可以实现静态链式编程
- 其中 staticName 用来设置静态创建方法的名称
- 当需要设置某个参数必须在创建时提供的话,可以在相应的参数上添加 @NonNull 注解
@Data@Accessors(chain = true) // 支持链式编程@RequiredArgsConstructor(staticName = "of")public class User implements Serializable {private static final long serialVersionUID = -1602774207630314992L;@NonNullprivate Integer id;private String username;private String password;}
builder 模式的链式 Bean
builder 模式实现原理为在 bean 里面创建一个 静态 builder 方法 和一个 静态内部Builder类,通过调用静态 builder 方法来创建 Builder 类,然后通过 builder 类中的 build 方法直接创建一个 Bean,具体实现:
public class User {private Integer id;private String name;private String password;public User(Integer id ,String name ,String password) {this.id = id;this.name = name;this.password = password;}// 静态 builder 方法public static User.Builder builder() {return new User.Builder();}// 静态内部类 Builderpublic static class Builder {private Integer id;private String name;private String password;public User.Builder id(Integer id) {this.id = id;return this;}public User.Builder name(String name) {this.name = name;return this;}public User.Builder password(String password) {this.password = password;return this;}public User build(){return new User(id ,name ,password);}}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}
使用:
public static void main(String[] args) {User user = User.builder().id(12).name("Bob").password("123456").build();}
lombok 实现 builder 模式的链式 bean
lombok 实现 builder 模式的链式 bean,只需要在相应 bean 上添加一个注解:@Builder ,@Builder 注解中支持如下参数:
- builderClassName = “Builder”:内部创建类的名称
- builderMethodName = “builder”:获取静态内部类的方法
- buildMethodName = “build”:创建方法名称
- toBuilder = true:是否创建一个 toBuilder 方法,用于将外部类转换成一个构造器 Builder
有关 Builder 的其他用法:https://www.jianshu.com/p/d08e255312f9@Data@Builderpublic class User implements Serializable {private static final long serialVersionUID = -1602774207630314992L;private Integer id;private String username;private String password;}
