Search code examples
javaanonymousfunctional-interface

What is the point of creating method reference from already exiting implementation of functional interface (like via anonymous class)?


interface Foo<T> {
    T apply(T double1, T double2);
}

public class Test {
    static void calculate(Double double1, Double double2, Foo<Double> func) {
        double result = func.apply(double1, double2);
        System.out.println(result);
    }
    
    public static void main(String[] args) {
        double double1 = 100;
        double double2 = 0.2;
        calculate(double1, double2, new Foo<Double>() {
            
            public Double apply(Double double1, Double double2) {
                return double1 * (1+double2);
            }
        }::apply);
       //^^^^^^^---- does it improve anything? (code will work without it)
    }
}

I don't understand the use of the syntax ::apply at the end of the anonymous class's construction. I don't understand why this doesn't cause a compilation error and I don't understand what it achieves.

If you remove ::apply, the program works. So why use double colons in this instance?


Solution

  • This is indeed a poor use of the :: operator. It's quite silly to explicitly construct an anonymous Foo<Double> instance just to turn around and use ::apply to extract the apply() implementation and create a second anonymous function object. It uses two equivalent idioms at the same time. One will do.

    As you say, it would be more sensible to leave off ::apply and use the anonymous object directly:

    calculate(double1, double2, new Foo<Double>() {
        public Double apply(Double double1, Double double2) {
            return double1 * (1+double2);
        }
    });
    

    Or ditch the anonymous Foo<Double> class and use 100% lambda syntax:

    calculate(double1, double2, (a, b) -> a * (1 + b));
    

    The latter would be my preference since it is so much more concise.