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

Art*_*dło 14 java java-8

我有以下一段代码

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

最后一行导致错误

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

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

Function<CharSequence,StringJoiner> addFunc = joiner::add;
Run Code Online (Sandbox Code Playgroud)

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

man*_*uti 11

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

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

       @Override
        public Integer apply(StringJoiner stringJoiner) {
            return stringJoiner.length;
        }
}
Run Code Online (Sandbox Code Playgroud)

你会这样称呼Function如下:

StringJoiner sj1 = ...  // an arbitrary StringJoiner
int sjLength1 = lengthFunc.apply(sj1);
Run Code Online (Sandbox Code Playgroud)

在契约中,StringJoiner.add(CharSequence)采用一个论证,所以总体上Function必须采取(1)arbirary实例StringJoiner,(2)CharSequence并返回a StringJoiner.

您可以改为将引用分配给BiFunction:

BiFunction<StringJoiner, CharSequence, StringJoiner> addFunc = StringJoiner::add;
Run Code Online (Sandbox Code Playgroud)

这相当于:

BiFunction<StringJoiner, CharSequence, StringJoiner> addFunc = new BiFunction<StringJoiner, CharSequence, StringJoiner>() {

       @Override
        public StringJoiner apply(StringJoiner stringJoiner, CharSequence charSequence) {
            return stringJoiner.add(charSequence);
        }
}
Run Code Online (Sandbox Code Playgroud)

并将使用如下:

StringJoiner sj1 = ...  // an arbitrary StringJoiner
sj1 = addFunc.apply(sj1, "a"); // no need to re-assign, but just to show the return type
Run Code Online (Sandbox Code Playgroud)

  • @ArturSkrzydło是的,您可能需要编写自己的功能界面或使用其他解决方法.您可能需要查看http://stackoverflow.com/questions/18400210/java-8-where-is-trifunction-and-kin-in-java-util-function-or-what-is-thealt. (2认同)

Era*_*ran 10

Function<StringJoiner,Integer> lengthFunc =  StringJoiner::length;
Run Code Online (Sandbox Code Playgroud)

lengthFunc是一个函数,它接受StringJoiner并返回一个Integer.因此,任何实例方法StringJoiner都不需要,并返回Integer匹配此接口.调用该方法的实例将是StringJoiner所需的实例Function<StringJoiner,Integer>.

另一方面

Function<CharSequence,StringJoiner> addFunc = StringJoiner::add
Run Code Online (Sandbox Code Playgroud)

addFunc是一个Function需要CharSequence和回报StringJoiner.没有StringJoiner匹配此接口的实例方法,因为该函数没有StringJoiner要应用该add方法的输入实例.

你需要一个BiFunction匹配签名StringJoiner::add:

BiFunction<StringJoiner,CharSequence,StringJoiner> addFunc = StringJoiner::add;
Run Code Online (Sandbox Code Playgroud)

  • 这个解释得非常好. (2认同)