为何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
相关产品推荐
相关产品推荐

