Java 如何在lamda表达式中使用super::methodName引用方法的超类版本
我正在学习Java 8中的Lambda表达式和方法引用,我们可以使用“super”来引用方法的超类版本,如下所示: 超级::名称 但当我这样做的时候,它就不起作用了。以下是示例代码: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;
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