加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 如何将简单的setter解释为Consumer?

发布时间:2020-12-15 04:38:30 所属栏目:Java 来源:网络整理
导读:首先,请耐心等待.大部分时间我在 Scala(有时只在JVM端)或其他语言工作,所以我的 Java(8)知识有点受限! 我必须重构的代码充满了空检查.我想让一些pojo的属性设置/覆盖更好一点,并且很高兴能够使用Java 8来完成工作. 所以我创造了这个: private T void setOn
首先,请耐心等待.大部分时间我在 Scala(有时只在JVM端)或其他语言工作,所以我的 Java(8)知识有点受限!

我必须重构的代码充满了空检查.我想让一些pojo的属性设置/覆盖更好一点,并且很高兴能够使用Java 8来完成工作.

所以我创造了这个:

private <T> void setOnlyIfNotNull(final T newValue,Consumer<T> setter) {
    if(newValue != null) {
        setter.accept(newValue);
    }
}

并像这样使用它:

setOnlyIfNotNull(newUserName,user::setName);

junit4-test看起来像这样:

@Test
public void userName_isOnlyUpdated_ifProvided() {
   User user = new User("oldUserName");

   UserUpdateRequest request = new UserUpdateRequest().withUserName("newUserName");   
service.updateUser(user,request); // This calls setOnlyIfNotNull behind the curtain. And it does invoke the setter ONLY once!

 assertThat(user.getUserName()).isEqualTo("newUserName");
}

这很有效.在我请同事进行代码审查之前,我对自己很满意.在解释我做了什么之后,他详细说明了他认为这不起作用,因为函数仍然没有Java中的一等公民,而User-pojo没有扩展FunctionalInterface.接口也是在类级别而不是功能级别上提供的.

现在我想知道,为什么测试工作,我在这里滥用了什么? Naive me只是想象Java编译器知道setter的T setT(T值)签名与Consumer< T>相同.

编辑:详细说明:如果我将测试更改为失败,例如with assertThat(user.getUserName()).isEqualTo(“Something”);失败的比较失败如预期!

解决方法

该评论在以下几个方面是错误的:

>接口功能不需要FunctionalInterface.它只是一个编译器提示,当标记有此注释的内容不符合条件时(仅仅是一个抽象方法的接口)标记错误

If a type is annotated with this annotation type,compilers are
required to generate an error message unless:

  • The type is an interface type and not an annotation type,enum,or
    class.
  • The annotated type satisfies the requirements of a functional
    interface.

However,the compiler will treat any interface meeting the
definition of a functional interface as a functional interface
regardless of whether or not a FunctionalInterface annotation is
present on the interface declaration.

>在任何情况下,用户都不应该是功能性的,它是Consumer接口,它是功能性的.
>虽然函数确实可能不是第一类值(虽然请参阅here以了解更多信息),但是user :: setFoo不是“原始”函数,它是一个构造,它创建一个实现Consumer的对象(在本例中),并且使用传入的任何参数调用user.setFoo().该机制表面上类似于匿名内部类如何声明类并立即创建实例. (但其背后的机制存在重大差异.)

但最有力的论据是,您的代码只能使用Java的官方和文档API来证明是有效的.所以说“但Java不支持这个”是一种奇怪的想法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读