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

为何Animal接口变量可持有Supplier类型方法引用?编译疑问

问题解析:为何Animal接口能持有Dog::new的引用?

先回顾你提供的代码:

定义的接口与实现类

public interface Animal {
    void makeVoice();
}
public class Dog implements Animal {
    @Override
    public void makeVoice() {
        System.out.println("aou aou");
    }
}

存在疑问的Main类代码

public class Main {
    public static void main(String[] args) {
        Animal dog = Dog::new; // 为何能编译?它应该是Supplier<Animal>类型

        dog.makeVoice(); // 未执行逻辑,因dog持有Lambda表达式而非Dog实例
    }
} 

1. 为什么Animal dog = Dog::new能编译?

核心原因是Animal是函数式接口(仅包含一个抽象方法makeVoice()),而Dog::new(无参构造器引用)可以适配这个函数式接口的方法签名。

Java的函数式接口适配规则允许:当接口的抽象方法是无参数、无返回值(() -> void)时,目标方法(这里是Dog的无参构造器,签名为() -> Dog)的返回值会被自动忽略,因此可以完成适配。

这段代码等价于:

Animal dog = () -> { new Dog(); };

编译器会自动丢弃构造器的返回值,使其符合Animal接口的方法签名要求。

2. 为什么调用dog.makeVoice()没有执行预期逻辑?

此时dog变量引用的并不是Dog的实例,而是一个实现了Animal接口的Lambda对象——这个Lambda的逻辑仅仅是创建一个Dog实例,并不会调用该实例的makeVoice()方法。

如果要执行Dog实例的makeVoice(),可以调整为以下两种方式:

  • 直接创建Dog实例:Animal dog = new Dog();
  • 修改Lambda逻辑,创建实例后调用方法:
Animal dog = () -> { new Dog().makeVoice(); };

内容的提问来源于stack exchange,提问作者Maor Hassid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:47:28