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

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"));
}



当我使用Lambdatut::stringLength时,我得到了一个类强制转换异常,因为String::length可以正常工作。在这里我很困惑,如何用length()函数替换函数接口S apply(T obj)中的方法
如果使用lamTut::stringLength,则会出现编译时异常:


  LambdaTut类型的方法funtionTut(Function)不适用于参数(lamTut :: stringLength)

最佳答案

stringLength()不接受任何参数,它是LambdaTut的一种方法。因此,将LabmdaTut::stringLength推断为Function<LambdaTut, Integer>

因此,对funtionTut()的调用中的通用类型T是LambdaTut。尽管T是LambdaTut,但是您将表达式("Name:" + a)强制转换为T。那不可能是正确的。

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

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


关于lamTut::stringLength,由于stringLength()不接受任何参数,因此它是一个不接受任何输入并返回Integer的函数。因此可以将其推断为Supplier<Integer>,而不能推断为Function,因为Function需要输入。

09-10 02:21