方法参考:功能界面

Dha*_*ari 2 java java-8 method-reference

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

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"));
}
Run Code Online (Sandbox Code Playgroud)
  1. 当我使用时Lambdatut::stringLength,我得到了一个类别转换异常,因为String::length工作正常.我在这里混淆了length()函数如何替换函数接口中的方法S apply(T obj)

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

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

JB *_*zet 5

stringLength()没有任何东西作为论据,并且是一种方法LambdaTut.所以LabmdaTut::stringLength推断为Function<LambdaTut, Integer>.

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

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

public <S> void funtionTut(Function<String, S> function)
Run Code Online (Sandbox Code Playgroud)

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

  • 需要输入:`this`.即任何实例方法实际上都是一个以`this`作为参数的函数,即调用该方法的字符串.`String.length()`,一旦表示为函数,相当于`int length(String s)`.如果你把`String :: length`写成一个lambda,你会得到`(String s) - > s.length()`.如果你把`lambdaTut :: stringLength`写成lambda,你得到`() - > lambdaTut.stringLength()`. (2认同)