我有以下一段我一直在努力理解方法参考的代码。
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需要输入。