目标类型
-
目标类型(Target Type)
- 目标方法所期望的数据类型。
因为 Java 编译器是通过 Lambda 表达式所在上下文或场景的目标类型来确定 Lambda 表达式的类型。故,我们只有在 Java 编译器可以确定目标类型的场景下,才能使用 Lambda 表达式。这样的场景有:
- 变量声明
- 赋值
return
语句- 数组初始化器
- 方法或构造函数参数
- Lambda 表达式体
- 条件表达式,
?:
- 强制转换表达式(Cast expression)
Java 编译器常使用两个语言特性来确定目标类型:
- 重载解析(overload resolution)
- 类型参数推断(type argument inference)
示例代码
假设我们有两个函数接口,且有两个重载方法分别以这两个函数接口作为其参数进行调用。代码如下:
package com.wuxianjiezh.test;
public class TargetTypeTest {
public interface SayHello {
void run();
}
public interface SayNothing<V> {
V run();
}
public void invoke(SayHello sayHello) {
System.out.print("Hello:");
sayHello.run();
}
public <T> T invoke(SayNothing<T> sayNothing) {
return sayNothing.run();
}
public static void main(String[] args) {
TargetTypeTest test = new TargetTypeTest();
test.invoke(() -> System.out.println("嗒嗒嗒")); // 调用 `invoke(SayHello)`
test.invoke(() -> "我是返回结果"); // // 调用 `invoke(SayNothing)`
}
}
如上代码所示,我们通过方法重载,创建了两个 invoke
方法,其中一个没有返回值(invoke(SayHello)
),另一个有返回值(invoke(SayNothing)
)。
因为 () -> System.out.println("嗒嗒嗒")
没有返回值,所以以其作为参数的 invoke
方法调用了 invoke(SayHello)
。
而 () -> "我是返回结果"
存在返回值,所以以其作为参数的 invoke
方法调用了 invoke(SayNothing)
。
以上代码的运行结果为:
Hello:嗒嗒嗒