-1

I don't understand why this code compiles without error or warning:

import java.util.ArrayList;
import java.util.List;

class A {}

interface I {
    void methodI();
}

public class B {
    public void test() {
        List<I> l = new ArrayList<>();
        l.add(A::new);
    }
}

After all, A::new should be a lambda (as shown when I print l.get(0) which gives B$$Lambda$/1/...), so I don't see why it could fit in a list of the I interface. (I'm using Java 8, but also tested with Java 10)

Pâris Douady
  • 833
  • 8
  • 18

1 Answers1

2

That's exactly how one uses lambdas and method references: by assigning them to a functional interface, an interface with a single abstract method. They don't compile otherwise.

If you were to inspect B$$Lambda$/1/... you'd find it's an auto-generated class that implements I.

These snippets are all equivalent:

l.add(A::new);
l.add(() -> new A());
l.add(() -> { new A(); });
l.add(new I() {
    @Override public void methodI() {
        new A();
    }
});

(Note that this isn't a useful method. It creates a new object and immediately throws it away. A::new is a valid match for void methodI(), but it's very likely a semantic error. It'd be better if the interface were something like A methodI() or Object methodI().)

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Note that this comes from a beginner's mistake, where they wanted to do l.add(new SomeObject()); but instead did l.add(SomeObject::new); by mistake. However since their interface only had one method (by chance), it compiled and their program didn't work. Thank you for your detailed answer, I didn't know any interface with one method was a functional interface. – Pâris Douady Nov 09 '19 at 13:08