为何ExecutorService::execute()可执行未实现Runnable接口的方法?
为什么用方法引用
this::foo能适配ExecutorService的execute()? 这问题问得特别到位!其实背后是Java 8引入的函数式接口和方法引用特性在帮你“偷偷干活”,我来一步步给你讲明白:
1. Runnable的本质是函数式接口
先看Runnable接口的定义:
@FunctionalInterface public interface Runnable { void run(); }
它被标记为@FunctionalInterface,意味着这是一个函数式接口——核心特征是只有一个抽象方法。Java 8之后,只要某个类型符合“单抽象方法”的要求,就可以用Lambda表达式、方法引用等方式来创建它的实例,而不需要显式写匿名内部类或者实现类。
2. 你的foo()方法刚好匹配Runnable的方法签名
你的foo()方法是public void foo():
- 无参数
- 返回值为
void
这和Runnable中run()方法的签名完全一致!这种情况下,Java编译器会自动把this::foo这个方法引用,转换成一个实现了Runnable接口的实例——相当于帮你自动生成了下面这段代码:
myExecutor.execute(new Runnable() { @Override public void run() { foo(); // 调用你的foo方法 } });
3. 是否必须显式使用Runnable对象?
答案是不需要。
ExecutorService的execute()方法确实要求传入Runnable类型,但Java 8的函数式编程特性允许你用更简洁的方式来提供符合要求的实例:
- 可以是传统的
new Runnable()匿名内部类 - 可以是Lambda表达式:
myExecutor.execute(() -> foo()); - 也可以是你用的方法引用
this::foo
只要你的代码能适配Runnable的单抽象方法签名,编译器就会自动完成类型转换,让程序正常运行。
内容的提问来源于stack exchange,提问作者Bohaterowicz
相关产品推荐
相关产品推荐

