方法引用 - 无效的方法引用 - 不能从静态上下文中引用

2022-09-03 06:04:02

我有以下代码

StringJoiner joiner = new StringJoiner(", ");
joiner.add("Something");
Function<StringJoiner,Integer> lengthFunc =  StringJoiner::length;
Function<CharSequence,StringJoiner> addFunc = StringJoiner::add;

最后一行导致错误

Error:(54, 53) java: invalid method reference
  non-static method add(java.lang.CharSequence) cannot be referenced from a static context

我知道这种方法不能以静态方式使用,我应该有这样的东西:

Function<CharSequence,StringJoiner> addFunc = joiner::add;

相反。然而,我不明白为什么第三行,与是java编译器完全正确。有人可以解释一下为什么吗?StringJoiner::length;


答案 1
Function<StringJoiner,Integer> lengthFunc =  StringJoiner::length;

lengthFunc是一个函数,它接受 a 并返回一个 .因此,该方法的任何实例方法都不带任何内容,并返回与此接口匹配的实例。调用该方法的实例将是 .StringJoinerIntegerStringJoinerIntegerStringJoinerFunction<StringJoiner,Integer>

另一方面

Function<CharSequence,StringJoiner> addFunc = StringJoiner::add

addFunc是一个,它接受 a 并返回 。没有与此接口匹配的实例方法,因为该函数没有要应用该方法的输入实例。FunctionCharSequenceStringJoinerStringJoinerStringJoineradd

您需要 与 以下签名匹配:BiFunctionStringJoiner::add

BiFunction<StringJoiner,CharSequence,StringJoiner> addFunc = StringJoiner::add;

答案 2

因为采用零个参数,所以方法引用总体上采用一个(任意实例)并返回一个 .换句话说,第一个分配的方法 ref 等效于:StringJoiner.lengthStringJoinerInteger

Function<StringJoiner, Integer> lengthFunc = new Function<StringJoiner, Integer>() {

       @Override
        public Integer apply(StringJoiner stringJoiner) {
            return stringJoiner.length;
        }
}

您可以按如下方式调用它:Function

StringJoiner sj1 = ...  // an arbitrary StringJoiner
int sjLength1 = lengthFunc.apply(sj1);

在合约中,取一个参数,因此总体而言,必须取 (1) 的 arbirary 实例 ,(2) 和返回一个 。StringJoiner.add(CharSequence)FunctionStringJoinerCharSequenceStringJoiner

您可以改为将引用分配给 执行该操作的:BiFunction

BiFunction<StringJoiner, CharSequence, StringJoiner> addFunc = StringJoiner::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

推荐