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

时间:2017-01-29 13:14:04

标签: java java-8

我有以下代码

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;

代替。但是我无法理解为什么第三行StringJoiner::length;对于java编译器是完全正确的。 someboedy可以解释一下为什么会这样吗?

2 个答案:

答案 0 :(得分:11)

因为StringJoiner.length取零参数,所以整个方法引用需要StringJoiner(任意实例)并返回Integer。换句话说,第一个指定的方法ref相当于:

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);

在合同中,StringJoiner.add(CharSequence)只接受一个参数,因此整体Function必须采用(1)StringJoiner,(2)CharSequence和返回StringJoiner

您可以将引用分配给执行该操作的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

答案 1 :(得分:10)

Function<StringJoiner,Integer> lengthFunc =  StringJoiner::length;

lengthFunc是一个获取StringJoiner并返回Integer的函数。因此,任何不带任何内容并返回StringJoiner的{​​{1}}实例方法都会匹配此接口。调用该方法的实例将是Integer所需的StringJoiner

另一方面

Function<StringJoiner,Integer>

Function<CharSequence,StringJoiner> addFunc = StringJoiner::add 是一个addFunc,需要Function并返回CharSequence。没有StringJoiner的实例方法与此接口匹配,因为该函数没有输入StringJoiner实例来应用StringJoiner方法。

您需要add来匹配BiFunction的签名:

StringJoiner::add