使用方法引用实现函数式接口时为何出现方法调用结果不符?
问题解析:方法引用与直接实例化函数式接口的行为差异
当使用方法引用将A类实例的myTest方法赋值给函数式接口MyIF变量后,调用myTest输出的是接口默认方法内容,而非A类重写后的方法;但直接实例化A赋值给MyIF变量却能得到预期的类重写方法结果,这两种写法的差异原因是什么?
代码1
@FunctionalInterface interface MyIF { void init(); default void myTest() { System.out.println("myTest interface Method"); } } class A implements MyIF { @Override public void init() { myTest(); } @Override public void myTest() { System.out.println("myTest class Method"); } } public class Main { public static void main(String[] args) { A a = new A(); MyIF my = a::myTest; my.myTest(); } }
代码1输出
myTest interface Method
代码1预期
myTest class Method
代码2
A a = new A(); MyIF my = new A(); my.myTest();
代码2输出
myTest class Method
差异原因
核心在于方法引用赋值给函数式接口时,生成的是仅实现了接口抽象方法的代理对象:
- 函数式接口
MyIF的抽象方法是init(),当你用a::myTest赋值给MyIF变量时,Java会创建一个代理类,这个类只实现了init()方法——把init()的逻辑替换成调用a的myTest()方法,但完全没处理默认方法myTest()。所以当你调用my.myTest()时,代理对象找不到类重写的myTest,就会执行接口的默认实现。 - 而直接
new A()赋值给MyIF变量时,这个对象是A类的实例,它完整实现了接口的抽象方法,并且重写了默认方法myTest(),调用时自然会执行A类里的重写版本。
简单说:方法引用生成的代理只关注抽象方法的实现,不会继承原类对默认方法的重写;直接实例化的类实例则完整保留了所有重写逻辑。
内容的提问来源于stack exchange,提问作者IM SEOKHYEON
相关产品推荐
相关产品推荐

