为什么
functionDemo3.test
会产生编译错误,即incompatible types: java.lang.Object cannot be converted to java.lang.String
?而 functionDemo.test
和 functionDemo2.test
则不然。
import java.util.function.Function;
public class FunctionTemplateDemo<T> {
public Object sayHello(String name) {
return "hello " + name;
}
public static void main(String[] args) {
FunctionTemplateDemo<String> functionDemo = new FunctionTemplateDemo<String>();
functionDemo.test(functionDemo::sayHello);
FunctionTemplateDemo<?> functionDemo2 = new FunctionTemplateDemo<Object>();
functionDemo2.test(functionDemo::sayHello);
FunctionTemplateDemo functionDemo3 = new FunctionTemplateDemo<Object>();
functionDemo3.test(functionDemo::sayHello);
}
private void test(Function<String, Object> function) {
Object hello = function.apply("hello");
System.out.println("say: " + hello);
}
}
functionDemo 之所以有效,是因为 FunctionTemplateDemo 显式定义了泛型类型,并且方法引用符合预期的函数签名。
functionDemo2 之所以有效,是因为 FunctionTemplateDemo 使用通配符,允许灵活性而不干扰函数签名。
functionDemo3 失败,因为使用原始类型会禁用类型安全,导致编译器推断出错误的类型(对象而不是字符串),从而导致方法引用签名不匹配。
原始类型(FunctionTemplateDemo)剥离了泛型类型信息,导致编译器将测试方法解释为期望的 Function
关键问题是 Function
将原始类型更改为适当的泛型类型可以解决问题:
FunctionTemplateDemo<Object> functionDemo3 = new FunctionTemplateDemo<>();
functionDemo3.test(functionDemo::sayHello);