方法参考:函数接口

Method reference : Function interface

我有以下一段代码,我一直在努力理解方法参考。

private static String s;

public static void main(String[] args) {
    // TODO Auto-generated method stub
    LambdaTut lamTut = new LambdaTut();
    Function<String, Integer> lenghthFunction = (a) -> a.length();
    lamTut.funtionTut(LambdaTut::stringLength);

}


public int stringLength() {
    System.out.println(s);
    return s.length();
}
public <T, S> void funtionTut(Function<T, S> function) {
    Function<T, String> sqFunction = function.andThen(a -> "Length:" + a);
    System.out.println(sqFunction.compose((a) -> (T) ("Name:" + a)).apply("Demo"));
}
  1. 当我使用 Lambdatut::stringLength 时,我得到一个 class 转换异常,而 String::length 工作正常。我在这里感到困惑 length() 函数如何替换函数接口中的方法 S apply(T obj)

  2. 如果我使用lamTut::stringLength,我得到一个编译时异常:

    The method funtionTut(Function) in the type LambdaTut is not applicable for the arguments (lamTut::stringLength)

在上面的代码中

此方法仅return整数使用实例字符串长度

public int stringLength() {
    System.out.println(s);
    return s.length();
}

但使用

lamTut.funtionTut(LambdaTut::stringLength);

functionTut 无法确定数据类型

只要改变你的功能

public int stringLength(String s) {
    System.out.println(s);
    return s.length();
}

它的作品

stringLength()不接受任何参数,是LambdaTut的一个方法。所以 LabmdaTut::stringLength 被推断为 Function<LambdaTut, Integer>.

所以您调用 funtionTut() 时的通用类​​型 T 是 LambdaTut。你将表达式 ("Name:" + a) 转换为 T,尽管 T 是 LambdaTut。这不可能是正确的。

顺便说一句,由于您要将 String 转换为 T,这意味着 T 的唯一可能类型是 String、Object、Serializable 等,并且泛型 T 甚至不应该存在。该方法应声明为

public <S> void funtionTut(Function<String, S> function)

关于lamTut::stringLength,因为stringLength()不接受任何参数,它是一个不接受任何输入的函数,returns是一个整数。因此它可以推断为 Supplier<Integer>,但不能推断为函数,因为函数需要输入。