使用带有接口的静态和非静态方法的链接

Using links to static and non-static methods with interface

为什么我可以从classString调用非静态方法length(),但我不能调用非静态 方法lengthHelper( String line ) 来自我的class ExpressionHelper?

public static void main(String[] args) {

    String[] lines1 = {"H", "HH", "HHH"};
    System.out.println(sum(lines1, String::length));
    System.out.println(sum(lines1, s -> s.length()));
    System.out.println(sum(lines1, ExpressionHelper::lengthHelper)); //wrong
}

interface Expression {
    int length(String line);
}

static class ExpressionHelper {

    int lengthHelper(String line) {
        return line.length();
    }
}

private static int sum(String[] lines, Expression func) {
    int result = 0;
    for (String i : lines) {
        result += func.length(i);
    }
    return result;
}

String::length是String的一个实例方法。它需要您提供的 运行 的字符串实例,因为您将 lines1 的元素传递给它。

ExpressionHelper::lengthHelper是ExpressionHelper的一个实例方法。除了显式 String line 参数外,它还需要 运行 的 ExpressionHelper 实例,您没有提供。

如果您在 ExpressionHelper 中将 lengthHelper 设为静态方法,则无需 ExpressionHelper 实例即可调用它。

除了

如果您这样更改代码:

public static void main( String[] args ) 
{
    final var expressionHelper = new ExpressionHelper();
    String[] lines1 = {"H", "HH", "HHH"};
    System.out.println(sum( lines1, String::length ) );
    System.out.println(sum( lines1, s -> s.length() ) );
    System.out.println(sum( lines1, ExpressionHelper::lengthHelper) ); //wrong
    System.out.println(sum( lines1, expressionHelper::lengthHelper) );
}

它也适用于 ExpressionHelper::lengthHelper(尽管我应该写得更好 ExpressionHelper.lengthHelper()ExpressionHelper#lengthHelper 以避免进一步混淆......)

是的,我知道,在这种情况下,将变量命名为与 class 相同的名称是令人讨厌的,只是首字母小写:它不支持可读性。

但现在 expressionHelper 是 @khelwood 在他们的回答中提到的 ExpressionHelper 的实例。