此代码示例
Collection<Number> values = transform(
getValuatedObjects(),
input -> getValueProvider().apply(input).getValue());
违反 sonarqube rule :
Replace lambdas with method references when possible
它是 Sonar 错误吗?
或者我真的可以使用方法引用吗?
最佳答案
您无法替换 lambda input -> getValueProvider().apply(input).getValue()
在不改变语义的情况下使用方法引用。
方法引用替换单个方法调用,因此它不能简单地替换由多个方法调用组成的 lambda 表达式。input -> getValueProvider().apply(input)
形式的 lambda 表达式可以替换为 getValueProvider()::apply
当且仅当 getValueProvider()
的评估时间没关系,因为在 lambda 形式中,该方法在每个 lambda 主体评估时调用,而对于方法引用,它只调用一次并捕获结果。
这类似于 x -> System.out.println(x)
之间的区别。和 System.out::println
在哪里读取字段的内容System.out
发生在不同的时间,但通常没关系。但是您应该意识到其中的区别。
在您的示例中,第三种方法 getValue()
被调用。使用方法引用来表达这一点的唯一方法需要像 Function
这样的函数式接口(interface)。它有像 andThen
这样的方法和/或 compose
.但是,Java 8 的工作方式需要将第一个方法引用转换为目标接口(interface)以调用组合方法,这绝不比您现在拥有的 lambda 表达式更容易阅读:((Function<X,Y>)getValueProvider()::apply).andThen(Y::getValue)
在哪里 Y
是类型,apply(input)
返回。
请注意,规则说“在可能的情况下用方法引用替换 lambdas”,这让您有空间说,“好吧,这是不可能的”,但是,我不确定您可以在多大程度上称其为“规则”……
关于java - Sonar : Replace this lambda with a method reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25606906/