我有以下代码

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编译器是完全正确的。有人可以解释一下为什么吗?

最佳答案

因为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

07-24 22:15