Java 方法引用-无效的方法引用-不能是来自静态上下文的引用
我有下面的代码Java 方法引用-无效的方法引用-不能是来自静态上下文的引用,java,java-8,Java,Java 8,我有下面的代码 StringJoiner joiner = new StringJoiner(", "); joiner.add("Something"); Function<StringJoiner,Integer> lengthFunc = StringJoiner::length; Function<CharSequence,StringJoiner> addFunc = StringJoiner::add; 我知道这个方法不能静态使用,我应该有如下的东西: F
StringJoiner joiner = new StringJoiner(", ");
joiner.add("Something");
Function<StringJoiner,Integer> lengthFunc = StringJoiner::length;
Function<CharSequence,StringJoiner> addFunc = StringJoiner::add;
我知道这个方法不能静态使用,我应该有如下的东西:
Function<CharSequence,StringJoiner> addFunc = joiner::add;
函数addFunc=joiner::add;
相反。但是我不明白为什么第三行是
StringJoiner::length代码>对于java编译器来说是完全正确的。有人能解释一下为什么会这样吗?因为StringJoiner.length
接受零参数,所以方法引用总体上接受StringJoiner
(任意实例)并返回一个整数。换句话说,第一个指定的方法ref相当于:
Function<StringJoiner, Integer> lengthFunc = new Function<StringJoiner, Integer>() {
@Override
public Integer apply(StringJoiner stringJoiner) {
return stringJoiner.length;
}
}
BiFunction<StringJoiner, CharSequence, StringJoiner> addFunc = new BiFunction<StringJoiner, CharSequence, StringJoiner>() {
@Override
public StringJoiner apply(StringJoiner stringJoiner, CharSequence charSequence) {
return stringJoiner.add(charSequence);
}
}
在契约中,StringJoiner.add(CharSequence)
接受一个参数,因此总体上,函数
必须接受(1)StringJoiner的任意实例,(2)CharSequence
并返回一个StringJoiner
您可以将引用指定给一个双功能
,该功能执行以下操作:
BiFunction<StringJoiner, CharSequence, StringJoiner> addFunc = StringJoiner::add;
addFunc
是一个函数,它接受CharSequence
并返回StringJoiner
。StringJoiner
的实例方法与此接口不匹配,因为该函数没有应用add
方法的输入StringJoiner
实例
您需要一个BiFunction
来匹配StringJoiner::add的签名:
BiFunction<StringJoiner,CharSequence,StringJoiner> addFunc = StringJoiner::add;
BiFunction addFunc=StringJoiner::add;
什么是StringJoiner的仲裁实例?我看到它被视为将调用apply方法的对象类型,但我不确定它是如何处理的works@ArturSkrzydło我已经详细阐述了它们如何使用纯匿名类进行等效。所谓任意实例,我指的是在调用方法引用的上下文中使用的某个实例。这是一个很好的匿名函数实现示例。@ArturSkrzydło是的,您可能需要编写自己的函数接口或使用其他解决方法。你可能想检查一下。要补充一点,我个人会避免使用TriFunction
(因为这会使代码更复杂),并使它更像一个复合函数,首先我将整数
附加到字符序列
,然后调用原始的双函数。这一点解释得非常清楚。现在,如果您使用的是joiner::add
,那么这将是一个有效的函数
。。。
BiFunction<StringJoiner, CharSequence, StringJoiner> addFunc = new BiFunction<StringJoiner, CharSequence, StringJoiner>() {
@Override
public StringJoiner apply(StringJoiner stringJoiner, CharSequence charSequence) {
return stringJoiner.add(charSequence);
}
}
StringJoiner sj1 = ... // an arbitrary StringJoiner
sj1 = addFunc.apply(sj1, "a"); // no need to re-assign, but just to show the return type
Function<StringJoiner,Integer> lengthFunc = StringJoiner::length;
Function<CharSequence,StringJoiner> addFunc = StringJoiner::add
BiFunction<StringJoiner,CharSequence,StringJoiner> addFunc = StringJoiner::add;