为什么泛型类方法参考会出现编译错误

问题描述 投票:0回答:1

为什么

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);
    }
}
java
1个回答
0
投票

functionDemo 之所以有效,是因为 FunctionTemplateDemo 显式定义了泛型类型,并且方法引用符合预期的函数签名。

functionDemo2 之所以有效,是因为 FunctionTemplateDemo 使用通配符,允许灵活性而不干扰函数签名。

functionDemo3 失败,因为使用原始类型会禁用类型安全,导致编译器推断出错误的类型(对象而不是字符串),从而导致方法引用签名不匹配。

原始类型(FunctionTemplateDemo)剥离了泛型类型信息,导致编译器将测试方法解释为期望的 Function。这与方法引用 functionDemo::sayHello 不兼容,该方法的类型为 Function

关键问题是 Function 和 Function 不可互换,因为输入类型(字符串与对象)不同。原始类型会导致编译器推断出需要字符串的对象,从而导致类型不匹配。

将原始类型更改为适当的泛型类型可以解决问题:

FunctionTemplateDemo<Object> functionDemo3 = new FunctionTemplateDemo<>();
functionDemo3.test(functionDemo::sayHello);
© www.soinside.com 2019 - 2024. All rights reserved.