Java中如何传入类setter方法作为参数并在泛型方法中调用
核心问题解答
针对你提出的两个疑问,直接给出结论:
User::setLogin这类未绑定具体实例的类setter方法引用,正确类型为BiConsumer<User, T>。这种类名::实例方法的方法引用形式,会将方法调用的目标实例作为隐式第一入参,setter本身的入参作为第二入参,且setter无返回值,完全匹配BiConsumer的函数式接口定义。- 在
applyAll方法中,遍历用户列表拿到每一个User实例后,调用BiConsumer的accept方法,传入当前实例、以及值生成函数根据索引算出的属性值,即可完成setter调用。
修正后可运行代码
User类
public class User { private String login; // 跨包调用时请将访问权限改为public public void setLogin(String login) { this.login = login; } // 如需打印/获取属性可自行添加getter public String getLogin() { return login; } }
UserBuilder类
import java.util.ArrayList; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Function; public class UserBuilder { private final List<User> users; // 构造方法,初始化指定数量的空User实例 public UserBuilder(int userCount) { users = new ArrayList<>(userCount); for (int i = 0; i < userCount; i++) { users.add(new User()); } } public <T> UserBuilder applyAll(BiConsumer<User, T> setter, Function<Integer, T> valueGenerator) { for (int index = 0; index < users.size(); index++) { // 传入当前User实例、生成的属性值,执行setter逻辑 setter.accept(users.get(index), valueGenerator.apply(index)); } return this; } public UserBuilder withLogin(Function<Integer, String> loginGenerator) { return applyAll(User::setLogin, loginGenerator); } // 其他属性的批量赋值方法可参照withLogin扩展,例: // public UserBuilder withAge(Function<Integer, Integer> ageGenerator) { // return applyAll(User::setAge, ageGenerator); // } public List<User> build() { // 避免外部修改内部列表状态,可返回副本:return new ArrayList<>(users); return users; } }
使用示例验证
你给出的调用逻辑可直接正常运行:
public class Test { public static void main(String[] args) { List<User> users = new UserBuilder(10) .withLogin(index -> "user_" + index) .build(); // 输出验证:依次打印user_0 到 user_9 users.forEach(user -> System.out.println(user.getLogin())); } }
内容的提问来源于stack exchange,提问作者Theo Cerutti
相关产品推荐
相关产品推荐

