代码之家  ›  专栏  ›  技术社区  ›  Ricardo Marimon

是否有一个类型可以保存Java类的所有可能的SETER引用,而不管所设置的类型是什么?

  •  5
  • Ricardo Marimon  · 技术社区  · 5 年前

    假设我们有一个非常简单的类:

    public class User {
    
        private Long id;
        private String name;
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    

    我正在做一个简单的binder类来填充一个用户,并希望向所需的属性发出信号。

    UserBinder binder = new UserBinder(user)
        .requires(User::setId)
        .requires(User::setName);
    

    以上将表明这两个属性都是必需的。当然我可以传递这些值 "id" "name" 而不是方法引用。但似乎传递setter是非常合适的,因为需要在绑定器内部调用setter。

    以下工作很好:

    public void requires(BiConsumer<User, Long> r) // for User::setId;
    public void requires(BiConsumer<User, String> r) // for User::setName;
    

    但以下失败:

    public void requires(BiConsumer<User, ?> r)
    

    是否有一个类型可以保存Java类的所有可能的SETER引用,而不管所设置的类型是什么?

    2 回复  |  直到 5 年前
        1
  •  3
  •   Denis Zavedeev Brian Kelly    5 年前

    可以将泛型参数添加到 requires 方法:

    public <T> void requires(BiConsumer<User, T> consumer)
    

    现在:

    new UserBinder(new User())
        .requires(User::setName);
    

    编译精细。


    您告诉过您需要将收到的消费者存储在某个集合中,并检查该集合是否已包含一些 consumer

    不幸的是你做不容易(看这个 question )

    作为解决方案,您可以创建 @FunctionalInterface 延伸 Serializable 使用与中相同的方法签名 BiConsumer 并比较序列化字节。见 this answer . 但记住你 不能依赖这种行为

        2
  •  5
  •   Naman    5 年前

    可以使用以下方法绑定类型:

    <T> void requires(BiConsumer<User, T> r) {
    }
    

    此外,如果您只要求这些参数,则可以为所需字段创建自定义构造函数,如下所示:

    public User(Long id, String name)
    

    要确保对象的实例化必须具有这些属性。