为什么方法引用需要对函数接口进行类型转换?

问题描述:

在此代码段中我的IDE (IDEA Intellij社区)建议将方法引用转换为函数接口。为什么方法引用需要对函数接口进行类型转换?

这是为什么?

public class MethodReferences { 

    public static void main(String[] strings) { 
     Function<String, Integer> f = Integer::parseInt; 

     Predicate<Person> personPredicate = p->convert(p.getAge(),Integer::parseInt) >10; 

     //This is fine 
     System.out.println(convert("123", f)); 

     //This is fine 
     System.out.println(convert("123", (Function<String, Integer>) Integer::parseInt)); 

     //This is NOT 
     System.out.println(convert("123", Integer::parseInt)); //x1 
    } 

    private static <T, S> T convert(S s, Function<S, T> stFunction) { 
     return stFunction.apply(s); 
    } 
} 

错误信息我行x1得到的是:

Error:(20, 19) java: reference to println is ambiguous 
    both method println(char[]) in java.io.PrintStream and method println(java.lang.String) in java.io.PrintStream match 

Error:(20, 35) java: incompatible types: inferred type does not conform to upper bound(s) 
    inferred: java.lang.Integer 
    upper bound(s): char[],java.lang.Object 
+0

我认为它与'Integer :: parseInt'有关系,它返回的是一个'int'而不是'Integer' – Aaron

+1

我无法用JDK 1.8.0_51重现这一点。我的代码编译并提供输出。你使用的是什么版本的JDK? – SMA

+0

@SMA代码不可编译... – Adelin

它不接受,因为parseInt函数方法有两种不同的类型。

其中之一是只接受一个String说法,另一个接受一个String和一个int类型:

static int parseInt(String s)

static int parseInt(String s, int radix)

在代码中,你使用第二个,所以你应该投下来。在Eclipse中,据我所知,IDE自动理解它属于什么;但在IntelliJ中,您应该为了安全和良好的编程而进行这种类型的转换。

+2

这不是我所看到的。 NB我不得不添加一个'Person'类,用'getAge()'返回'String'来重现,此时javac报告'println(char [])'和'println(String)'之间的不明确性,没有看到简单的解释。 OTOH,'parseInt(String,int)'不在计算中,因为'R Function.apply(T)'的实现只能带一个参数。 –