Do method references skip the overhead of the lambda wrapper? Might they in the future?
According to the Java Tutorial on Method References:
Sometimes… a lambda expression does nothing but call an existing method.
In those cases, it's often clearer to refer to the existing method by
name. Method references enable you to do this; they are compact,
easy-to-read lambda expressions for methods that already have a name.
I prefer the lambda syntax to the method reference syntax for several reasons:
Lambdas are clearer
Despite Oracle's claims, I find the lambda syntax easier-to-read than the object method reference short-hand because the method reference syntax is ambiguous:
Bar::foo
Are you calling a static one-argument method on the class of x and passing it x?
x -> Bar.foo(x)
Or are you calling a zero-argument instance method on x?
x -> x.foo()
The method reference syntax could stand in for either one. It hides what your code is actually doing.
Lambdas are safer
If you reference Bar::foo as a class method and Bar later adds an instance method of the same name (or vice-versa), your code will no longer compile.
You can use lambdas consistently
You can wrap any function in a lambda – so you can use the same syntax consistently everywhere. The method reference syntax won't work on methods that take or return primitive arrays, throw checked exceptions, or have the same method name used as an instance and a static method (because the method reference syntax is ambiguous about which method would be called). They don't work when you have overloaded methods with the same number of arguments, but you shouldn't do that anyway (see Josh Bloch's item 41) so we can't hold that against method references.
Conclusion
If there's no performance penalty for doing so, I'm tempted to turn off the warning in my IDE and use the lambda syntax consistently without sprinkling the occasional method reference into my code.
P.S.
Neither here nor there, but in my dreams, object method references look more like this and apply invoke-dynamic against the method directly on the object without a lambda wrapper:
_.foo()
Best Answer
In many scenarios, I think lambda and method-reference is equivalent. But the lambda will wrap the invocation target by the declaring interface type.
For example
You will see the console output the stacktrace.
In
lambda()
, the method callingtarget()
islambda$lambda$0(InvokeTest.java:20)
, which has traceable line info. Obviously, that is the lambda you write, the compiler generates an anonymous method for you. And then, the caller of the of the lambda method is something likeInvokeTest$$Lambda$2/1617791695.run(Unknown Source)
, that is theinvokedynamic
call in JVM, it means the call is linked to the generated method.In
methodReference()
, the method callingtarget()
is directly theInvokeTest$$Lambda$1/758529971.run(Unknown Source)
, it means the call is directly linked to theInvokeTest::target
method.Conclusion
Above all, compare to method-reference, using lambda expression will only cause one more method call to the generating method from lambda.