Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 方法参考的组成_Java_Eclipse_Java 8_Function Composition_Method Reference - Fatal编程技术网

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