如何在 lambda 表达式中使用 super::methodName 引用方法的超级 class 版本

How to refer to super class version of a method using super::methodName in lamda expression

我正在学习 Java 8 中的 Lambda 表达式和方法引用,发现我们可以通过使用 'super' 引用超 class 版本的方法,如:

超级::名字

但是当我这样做时,它不起作用。这是示例代码:

interface MyInterface {
int someFunc(int x);
}

    class A {
    static int Func(int y) {
        // return (int) (Math.random() * y);
        return y;
    }
}

class B extends A {
    static int Func(int y) {
        // return (int) (Math.random() * y);
        return y + 1;
    }
}

public class Test {
    public static void main(String[] args) {
        System.out.print("Enter a number: ");
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        int result = funcOp(B::Func, scanner.nextInt()); // <-This works.
//int result = funcOp(B.super::Func, scanner.nextInt());  <--This is not working. 
//Getting: error: not an enclosing class: B
            int result = funcOp(B.super::Func, scanner.nextInt());
                                 ^
        scanner.close();
        System.out.println(result);
    }

    static int funcOp(MyInterface mI, int num) {
        return mI.someFunc(num);
    }
}

请告诉我,我执行此代码是否有误?据我了解,我们可以传递一个方法 "X" 作为参考,因为方法 "X" 满足方法 [=] 的条件和行为,因此预期功能接口的方法 "Y" 的实现26=] 并可能在那种情况下替换方法 "Y"。

这不对吗,我是不是以错误的方式获取了方法引用?

感谢您对此的投入:)

来自the JLS

The form super.Identifier refers to the field named Identifier of the current object, but with the current object viewed as an instance of the superclass of the current class.

[...]

The forms using the keyword super are valid only in an instance method, instance initializer, or constructor of a class, or in the initializer of an instance variable of a class. If they appear anywhere else, a compile-time error occurs.

您正在从 class 类型调用 super,因此出现编译错误。

正如许多人在评论中建议的那样,您应该在 funcOp 方法中传递 A::Func


请注意,您也无法从 Func 方法中调用 super,因为它是 static 方法,因此它不依赖于 class实例。


根据 OP 的评论进行编辑

您可以在实例方法中使用 super 关键字(因此,如果您删除静态),它看起来像这样:

class B extends A {
    int Func(int y) {
        // e.g:
        if (y > 10) {
            return super.Func(y); // call Func from the parent class
        }
        return y + 1;
    }
}

superthis 关键字是引用某个对象的引用变量。换句话说它属于 class.

的实例

如果您正在寻找替代方法而不是 A::Func

,您可以这样做
class B extends A {

static int Func(int y) {
    // return (int) (Math.random() * y);
    return y + 1;
}

public int getSuperFunc(int y)
{
    //call A class Func(int y)
    return super.Func(y);
}

}

并且在测试class主要方法

System.out.print("Enter a number: ");
java.util.Scanner scanner = new java.util.Scanner(System.in);
//int result = funcOp(B::Func, scanner.nextInt()); // <-This works.

B b=new B();              
int result1 = funcOp(b::getSuperFunc, scanner.nextInt()); // <-This works.

scanner.close();
System.out.println(result1);

输出

Enter a number: 1
1