方法引用不满足功能接口契约,但它编译.怎么可能?

kuc*_*raf 5 java-8 java-stream method-reference

在下面的类中,我将方法引用WordCounterEx::accumulate作为第二个参数传递给reduce方法.reduce方法的签名是:

<U> U reduce(U identity,
             BiFunction<U, ? super T, U> accumulator,
             BinaryOperator<U> combiner);
Run Code Online (Sandbox Code Playgroud)

因此reduce方法的第二个参数必须满足BiFunction配方.但是传递的累积方法不是BiFunction(它只有一个参数).为什么还要编译?

public class WordCounterEx {
    private final int counter;
    private final boolean lastSpace;

    public WordCounterEx(int counter, boolean lastSpace) {
        this.counter = counter;
        this.lastSpace = lastSpace;
    }

    public int countWords(Stream<Character> stream) {
        WordCounterEx wordCounter = stream.reduce(new WordCounterEx(0, true),
                //HOW CAN THIS WORK? here must come BiFunction - R apply(T t, U u);
                WordCounterEx::accumulate,
                WordCounterEx::combine);
        return wordCounter.counter;
    }

    public WordCounterEx accumulate(Character c) {
        if(Character.isWhitespace(c)) {
            return lastSpace ?
                    this :
                    new WordCounterEx(counter, true);
        } else {
            return lastSpace ?
                    new WordCounterEx(counter+1, false) :
                    this;
        }
    }

    public WordCounterEx combine(WordCounterEx wordCounter) {
        return new WordCounterEx(counter + wordCounter.counter
                ,wordCounter.lastSpace /*does not matter*/);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ole*_*.V. 3

accumulate()是一个实例方法,您可以通过类名和方法名(而不是实例和方法名)来引用它。因此,如果我想调用您给我的方法,我通常会这样做myEx.accumulate(myCh)。因此我提供了两件事:WordCounterEx实例和人物。因此,以这种方式使用的方法算作BiFunction<WordCounterEx, ? super Character, WordCounterEx>.

\n\n

例如,如果您给了我this::accumulate,则调用该方法的对象将被给定(this),并且它不能再用作BiFunction(在我的 Eclipse 中,我得到 \xe2\x80\x9c 方法 reduce(U, BiFunction Stream 类型中的 BinaryOperator) 不适用于参数 (WordCounterEx, this::accumulate, WordCounterEx::combine)\xe2\x80\x9d)。

\n

  • 请注意,在 Java 8 中,您可以将 `this` 作为参数传递,它与签名完美匹配:`public WordCounterExaccumulate(WordCounterEx this, Character c)`。这相当于没有“this”作为参数的版本,就像问题中一样。 (2认同)