Java 方法参考的组成
这与这个问题有关: 我注意到一个方法引用可以分配给一个声明为Java 方法参考的组成,java,eclipse,java-8,function-composition,method-reference,Java,Eclipse,Java 8,Function Composition,Method Reference,这与这个问题有关: 我注意到一个方法引用可以分配给一个声明为函数的变量,因此我假设它应该有和或组合函数,因此我希望我们可以直接组合它们。但显然,在调用之前,我们需要先将它们赋给声明为函数的变量(或在调用之前键入cast),然后才能对它们调用或组合 我怀疑我可能对这应该如何工作有一些误解 所以我的问题是: 为什么在调用和方法之前,我们需要先键入cast或将其赋值给变量 需要以这种方式执行的方法引用的具体类型是什么 下面是示例代码 public class MyMethods{ public
函数的变量,因此我假设它应该有和或组合函数,因此我希望我们可以直接组合它们。但显然,在调用之前,我们需要先将它们赋给声明为函数的变量(或在调用之前键入cast),然后才能对它们调用或组合
我怀疑我可能对这应该如何工作有一些误解
所以我的问题是:
为什么在调用和方法之前,我们需要先键入cast或将其赋值给变量
需要以这种方式执行的方法引用的具体类型是什么
下面是示例代码
public class MyMethods{
public static Integer triple(Integer a){return 3*a;}
public static Integer quadruple(Integer a){return 4*a;}
public int operate(int num, Function<Integer, Integer> f){
return f.apply(num);
}
public static void main(String[] args){
MyMethods methods = new MyMethods();
int three = methods.operate(1, MyMethods::triple); // This is fine
// Error below
// int twelve = methods.operate(1, (MyMethods::triple).andThen(MyMethods::quadruple));
// But this one is fine
Function<Integer, Integer> triple = MyMethods::triple;
Function<Integer, Integer> quadruple = MyMethods::quadruple;
int twelve = methods.operate(1, triple.andThen(quadruple));
// This one is also fine
int twelve2 = methods.operate(1, ((Function<Integer, Integer>)MyMethods::triple).andThen(MyMethods::quadruple));
}
}
公共类MyMethods{
公共静态整数三元组(整数a){返回3*a;}
公共静态整数四倍(整数a){返回4*a;}
公共整数运算(整数,函数f){
返回f.apply(num);
}
公共静态void main(字符串[]args){
MyMethods=新的MyMethods();
int three=methods.operate(1,MyMethods::triple);//这很好
//下面的错误
//int十二=方法。操作(1,(MyMethods::triple)和(MyMethods::triple));
//但是这个很好
函数triple=MyMethods::triple;
函数四重=MyMethods::四重;
int十二=方法运算(1,三重和四重);
//这个也可以
int twelve2=方法。操作(1,((函数)MyMethods::triple)和(MyMethods::triple));
}
}
更多关于错误的描述
在Eclipse中,它会突出显示错误消息:
此表达式的目标类型必须是函数接口
在Java 8编译器中,错误是:
java8test.java:14: error: method reference not expected here
int twelve = methods.operate(1, (MyMethods::triple).andThen(MyMethods::quadruple));
^
1 error
java8test.java:14:错误:此处不需要方法引用
int十二=方法。操作(1,(MyMethods::triple)和(MyMethods::triple));
^
1错误
(实际上,为什么Eclipse中的错误与Java 8编译器中的错误不同?正如Brian Goetz(Java lambdas项目负责人)所说,(这也适用于方法引用)。这就是为什么您需要在类型函数
的方法可用之前将其强制转换(或赋值)到该类型
Eclipse显示来自JDK编译器(javac)的不同错误消息的原因是Eclipse使用自己的Java编译器,称为ecj,这是一个与javac完全不同的程序。顺便说一句,这就是为什么Eclipse可以在JRE上运行,而不需要完整的JDK安装。如果您创建一个静态帮助器方法(其中所有函数都是参数而不是方法调用接收者),则无需类型转换或临时变量即可:
但是,请记住,与简单的lambda表达式相比,这种链接方法引用的源代码更短,运行时效率也更高:
int twelve = methods.operate(1, i -> quadruple(triple(i)));
请注意,上一个解决方案如何不需要类型转换、附加变量或助手方法。方法引用是一个很好的工具,如果你已经有了一个适合函数需要的方法,但是用多个方法引用组合一个函数并不是很有用(在大多数情况下)。我明白了,这个问题是关于谓词的,这就是为什么我在搜索中找不到它。谢谢你的回答!嗯,是的,我忘了我们可以恢复使用lambda表达式。谢谢你的意见!
int twelve = methods.operate(1, chain(MyMethods::triple, MyMethods::quadruple));
int twelve = methods.operate(1, i -> quadruple(triple(i)));