Java 如何在lamda表达式中使用super::methodName引用方法的超类版本

Java 如何在lamda表达式中使用super::methodName引用方法的超类版本,java,lambda,java-8,method-reference,Java,Lambda,Java 8,Method Reference,我正在学习Java 8中的Lambda表达式和方法引用,我们可以使用“super”来引用方法的超类版本,如下所示: 超级::名称 但当我这样做的时候,它就不起作用了。以下是示例代码: interface MyInterface { int someFunc(int x); } class A { static int Func(int y) { // return (int) (Math.random() * y); return y;

我正在学习Java 8中的Lambda表达式和方法引用,我们可以使用“super”来引用方法的超类版本,如下所示:

超级::名称

但当我这样做的时候,它就不起作用了。以下是示例代码:

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);
    }
}
接口MyInterface{
int-someFunc(int-x);
}
甲级{
静态int Func(int y){
//返回值(int)(Math.random()*y);
返回y;
}
}
B类扩展了A类{
静态int Func(int y){
//返回值(int)(Math.random()*y);
返回y+1;
}
}
公开课考试{
公共静态void main(字符串[]args){
System.out.print(“输入一个数字:”);
java.util.Scanner Scanner=新的java.util.Scanner(System.in);
int result=funcOp(B::Func,scanner.nextInt());//来自:

表单super.Identifier引用当前对象的名为Identifier的字段,但当前对象被视为当前类的超类的实例

[……]

使用关键字super的表单仅在类的实例方法、实例初始值设定项或构造函数中有效,或在类的实例变量的初始值设定项中有效。如果它们出现在其他任何地方,则会发生编译时错误。

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

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


请注意,您也不能从
Func
方法调用
super
,因为它是一个
static
方法,所以它不绑定到类实例


编辑OP评论后的内容

您可以从实例方法中使用
super
关键字(因此,如果您删除static),它如下所示:

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;
    }
}

super关键字是引用某个对象的引用变量。换句话说,它属于类的实例

如果您正在寻找替代方法,而不是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);
}

}
和在测试类中的主要方法

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);

Func
是静态的,您可以在这里使用
A::Func
。我真的不明白这一点,为什么不调用
A::Func
?调用B.super会得到什么?我只是在尝试学习引用方法的所有方法。静态方法是唯一的问题吗?因为动态方法调用只起作用在实例方法上。是这样吗?:)您不能从该类外部使用类的
super
。这会破坏很多东西。例如,如果您将使用
ItemContainer
RedItemsContainer extensed ItemContainer
,两者都使用
add(item)
但是
RedItemsContainer
重写该方法以仅允许红色项,并且您可以从外部调用RedItemsContainer的超级版本,您可以将非红色项添加到其中。谢谢。我现在理解了。然后我将完全避免此模式。明白了。如果我将方法更改为实例类型,我可以执行类似于是“new B().super::Func”还是仅将方法句柄用作示例:
int Func(int y){Function f=super::Func;return y>10?f.apply(y):y+1;}
Enter a number: 1
1