思考
封装一个set对象构建器,利用类的 set 引用方法(不局限set开头的方法)来设值,便于点式调用。
测试
import cn.hutool.core.bean.BeanUtil;
import lombok.Data;
@Data
public class User {
private String name;
private Integer age;
private String sex;
private String email;
private String other;
public void appendOther(String other) {
this.other = other;
}
public static void main(String[] args) {
// 方法1,普通语法(推荐)
User user1 = new User();
user1.setName("Jojo");
user1.setAge(18);
user1.setSex("女");
user1.setEmail("JoJo@example.com");
user1.appendOther("其他数据");
System.out.println(user1);
// 方法2,双括号语法(本质是匿名函数。不推荐使用,可能引起内存泄露)
User user2 = new User() {{
setName("Jojo");
setAge(18);
setSex("女");
setEmail("JoJo@example.com");
appendOther("其他数据");
}};
System.out.println(user2);
// 方法3:set 构建器(推荐)
final User user3 = SetBuilder.of(new User())
.set(User::setName, "JoJo")
.set(User::setAge, 18)
.set(User::setSex, "女")
.set(User::setEmail, "JoJo@example.com")
.set(User::appendOther, "其他数据")
.build();
System.out.println(user3);
// 方法4:反射设值
final User user4 = new User();
BeanUtil.setFieldValue(user4, "name", "JoJo");
BeanUtil.setFieldValue(user4, "age", 18);
BeanUtil.setFieldValue(user4, "sex", "女");
BeanUtil.setFieldValue(user4, "email", "JoJo@example.com");
BeanUtil.setFieldValue(user4, "other", "其他数据");
System.out.println(user4);
}
/**
* 打印:
User(name=Jojo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
User(name=Jojo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
User(name=JoJo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
User(name=JoJo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
*/
}
源码
/**
* 封装一个set构建器,基于对象的 set 引用方法来设值
* <p>
* @param <T> 指定对象泛型
*/
public class SetBuilder<T> {
private final T object;
public static <T> SetBuilder<T> of(T object) {
return new SetBuilder<>(object);
}
/**
* 构造函数
*
* @param object 对象
*/
public SetBuilder(T object) {
this.object = object;
}
/**
* 链式调用
*
* @param setter set引用方法
* @param value 要设置的属性值
* @param <V> 对象泛型
* @return builder,可链式调用
*/
public <V> SetBuilder<T> set(Setter<T, V> setter, V value) {
setter.set(object, value);
return this;
}
/**
* 构建
*
* @return 构建后对象
*/
public T build() {
return object;
}
@FunctionalInterface
public interface Setter<T, V> {
/**
* 调用set方法
*
* @param t 实体对象
* @param value 实体对象属性值
*/
void set(T t, V value);
}
}