You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用方法引用实现函数式接口时为何出现方法调用结果不符?

问题解析:方法引用与直接实例化函数式接口的行为差异

当使用方法引用将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 09:10:29