-2
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?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Chandz
  • 21
  • 4
  • 1
    Thank you @Pshemo. However, this explains the use of double colon which I understand but I don't understand why it has been added to the end of an anonymous class when it doesn't need to be there. If you remove ::apply the program still works so why put it there in the first place. – Chandz Nov 13 '20 at 17:39
  • In that case I would suggest to use [edit] option to clarify your question. Otherwise I am afraid that some people will simply mark it as duplicate of question I provided in first comment (which will prevent new answers to be posted here). – Pshemo Nov 13 '20 at 17:41

1 Answers1

1

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.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Thank you. Excellent explanation - code came from a reputable source so I was really confused. – Chandz Nov 13 '20 at 18:02