Why doesn't the first of the following examples work?
run(R::new);methodR.runis not called.run(new R());methodR.runis called.
Both examples are compiled-able.
public class ConstructorRefVsNew {
public static void main(String[] args) {
new ConstructorRefVsNew().run(R::new);
System.out.println("-----------------------");
new ConstructorRefVsNew().run(new R());
}
void run(Runnable r) {
r.run();
}
static class R implements Runnable {
R() {
System.out.println("R constructor runs");
}
@Override
public void run() {
System.out.println("R.run runs");
}
}
}
The output is:
R constructor runs
-----------------------
R constructor runs
R.run runs
In the first example, the R constructor is called, it returns lambda (which is not object):
But then how is it possible, that the example is compiled successfully?

Your
runmethod takes aRunnableinstance, and that explains whyrun(new R())works with theRimplementation.R::newis not equivalent tonew R(). It can fit the signature of aSupplier<Runnable>(or similar functional interfaces), butR::newcannot be used as aRunnableimplemented with yourRclass.A version of your
runmethod that can takeR::newcould look like this (but this would be unnecessarily complex):Because the compiler can make a
Runnableout of the constructor call, and that would be equivalent to this lambda expression version:The same applies to these statements:
But, as you can notice, the
Runnablecreated withR::newdoes just callnew R()in itsrunmethod body.A valid use of a method reference to execute
R#runcould use an instance, like this (but you'd surely rather use therinstance directly, in this case):