Let me offer some perspective on why we added this feature to the language, when clearly we didn't strictly need to (all methods refs can be expressed as lambdas).

Note that there isn't any right answer. Anyone who says "always use a method ref instead of a lambda" or "always use a lambda instead of a method ref" should be ignored.

This question is very similar in spirit to "when should I use a named class vs an anonymous class"? And the answer is the same: when you find it more readable. There are certainly cases that are definitely one or definitely the other, but there's a host of grey in the middle, and judgment must be used.

The theory behind method refs is simple: names matter. If a method has a name, then referring to it by name, rather than by an imperative bag of code that ultimately just turns around and invokes it, is often (but not always!) more clear and readable.

The arguments about performance or about counting characters are mostly red herrings, and you should ignore them. The goal is writing code that is crystal clear what it does. Very often (but not always!) method refs win on this metric, so we included them as an option, to be used in those cases.

A key consideration about whether method refs clarify or obfuscate intent is whether it is obvious from context what is the shape of the function being represented. In some cases (e.g., map(Person::getLastName), it's quite clear from the context that a function that maps one thing to another is required, and in cases like this, method references shine. In others, using a method ref requires the reader to wonder about what kind of function is being described; this is a warning sign that a lambda might be more readable, even if it is longer.

Finally, what we've found is that most people at first steer away from method refs because they feel even newer and weirder than lambdas, and so initially find them "less readable", but over time, when they get used to the syntax, generally change their behavior and gravitate towards method references when they can. So be aware that your own subjective initial "less readable" reaction almost certainly entails some aspect of familiarity bias, and you should give yourself a chance to get comfortable with both before rendering a stylistic opinion.

Answer from Brian Goetz on Stack Overflow
Top answer
1 of 6
308

Let me offer some perspective on why we added this feature to the language, when clearly we didn't strictly need to (all methods refs can be expressed as lambdas).

Note that there isn't any right answer. Anyone who says "always use a method ref instead of a lambda" or "always use a lambda instead of a method ref" should be ignored.

This question is very similar in spirit to "when should I use a named class vs an anonymous class"? And the answer is the same: when you find it more readable. There are certainly cases that are definitely one or definitely the other, but there's a host of grey in the middle, and judgment must be used.

The theory behind method refs is simple: names matter. If a method has a name, then referring to it by name, rather than by an imperative bag of code that ultimately just turns around and invokes it, is often (but not always!) more clear and readable.

The arguments about performance or about counting characters are mostly red herrings, and you should ignore them. The goal is writing code that is crystal clear what it does. Very often (but not always!) method refs win on this metric, so we included them as an option, to be used in those cases.

A key consideration about whether method refs clarify or obfuscate intent is whether it is obvious from context what is the shape of the function being represented. In some cases (e.g., map(Person::getLastName), it's quite clear from the context that a function that maps one thing to another is required, and in cases like this, method references shine. In others, using a method ref requires the reader to wonder about what kind of function is being described; this is a warning sign that a lambda might be more readable, even if it is longer.

Finally, what we've found is that most people at first steer away from method refs because they feel even newer and weirder than lambdas, and so initially find them "less readable", but over time, when they get used to the syntax, generally change their behavior and gravitate towards method references when they can. So be aware that your own subjective initial "less readable" reaction almost certainly entails some aspect of familiarity bias, and you should give yourself a chance to get comfortable with both before rendering a stylistic opinion.

2 of 6
19

Long lambda expressions consisting of several statements may reduce the readability of your code. In such a case, extracting those statements in a method and referencing it may be a better choice.

The other reason may be re-usability. Instead of copy&pasting your lambda expression of few statements, you can construct a method and call it from different places of your code.

🌐
DZone
dzone.com › coding › java › java lambda expressions vs method references
Java Lambda Expressions vs Method References
April 9, 2013 - In summary, there are circumstances in which we would like to use some preexisting code as the implementation for a functional interface, in those case we could use one of several variants of method references instead of a more verbose lambda expression.
Discussions

Is there a performance benefit to using the method reference syntax instead of lambda syntax in Java 8? - Software Engineering Stack Exchange
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... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
March 26, 2015
[Java] What is difference between method reference and lambda expression?
They're both ways to pass in functions as argument to another function. They don't have anything to do with forEach in particular, it's just that forEach is an example of when passing in a function is useful. In Java, it's technically not possible to actually just pass in a function. So you need to instantiate an object that implement a function interface and pass that in, instead. This is annoying, especially if you literally only want this function for this particular line. Lambda is a way to skipping through this entire process; it let you define a function (and the corresponding object) and pass it in right there, you don't even need to give them names. But unfortunately, this creates the annoying scenario where, you already have a function with names and everything, but you don't have a functional interface for that, so you write a lambda expression that literally just invoke this function. So a band-aid fix was added: you can literally just write in the name of the function, and Java will automatically do the rest for you. This is method reference. It lets you write code in such a way that it looks like you pass in a function as an argument, while technically do not allow you to do so. More on reddit.com
🌐 r/learnprogramming
3
1
September 11, 2022
Using lambda and method reference differ significantly in performance with Java 8 streams - Support - Kotlin Discussions
I have found that when working with Java 8 streams, using lambda and method reference can differ significantly in performance. Here is the code to invert an array of 1 GB executed both sequentially and in parallel: inl… More on discuss.kotlinlang.org
🌐 discuss.kotlinlang.org
2
September 27, 2020
Method Reference vs Lambda - Language Design - Kotlin Discussions
Recently I had a problem related to replacing lambda with method reference. Imagine that we have Button class which takes listener into constructor class Button( private val onClick: () -> Unit ) { fun performClick() = onClick() } Also we have ButtonClickListener class which represents button ... More on discuss.kotlinlang.org
🌐 discuss.kotlinlang.org
0
February 28, 2021
🌐
Reddit
reddit.com › r/java › subtle difference between lambda and method reference
r/java on Reddit: Subtle difference between lambda and method reference
September 23, 2022 -

So. Turns out there's a subtle difference between lambdas and method references. For instance, compare: myInstance::getStuff and () -> myInstance.getStuff()

This will mostly be considered equivalent. But. If myInstance happens to be null, the lambda will throw a null pointer when the lambda gets evaluated, but the method reference will throw right away when trying to access the reference.

So what? Well. This IS important if the code evaluating the lambda is inside a null-pointer try-catch.

Say I have a function mightBeNull(Supplier<T> function) that does something along the lines of:

try {
    doStuff(function.get().getSomeMore().getSomeMore());
} catch (NullPointerException e) {
    doOtherStuff();
}

If so. The call: mightBeNull(() -> myNullVariable.getStuff()) will work without exceptions, but the "equivalent": mightBeNull(myNullVariable::getStuff) will throw a null pointer exception right att the function call.

Top answer
1 of 3
20

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

public class InvokeTest {

    private static void invoke(final Runnable r) {
        r.run();
    }

    private static void target() {
        new Exception().printStackTrace();
    }

    @Test
    public void lambda() throws Exception {
        invoke(() -> target());
    }

    @Test
    public void methodReference() throws Exception {
        invoke(InvokeTest::target);
    }
}

You will see the console output the stacktrace.

In lambda(), the method calling target() is lambda$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 like InvokeTest$$Lambda$2/1617791695.run(Unknown Source), that is the invokedynamic call in JVM, it means the call is linked to the generated method.

In methodReference(), the method calling target() is directly the InvokeTest$$Lambda$1/758529971.run(Unknown Source), it means the call is directly linked to the InvokeTest::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.

2 of 3
38

It's all about the metafactory

First, most method references do not need desugaring by the lambda metafactory, they are simply used as the reference method. Under the section "Lambda body sugaring" of the Translation of Lambda Expressions ("TLE") article:

All things being equal, private methods are preferable to nonprivate, static methods preferable to instance methods, it is best if lambda bodies are desugared into in the innermost class in which the lambda expression appears, signatures should match the body signature of the lambda, extra arguments should be prepended on the front of the argument list for captured values, and would not desugar method references at all. However, there are exception cases where we may have to deviate from this baseline strategy.

This is further highlighted further down in TLE's "The Lambda Metafactory":

metaFactory(MethodHandles.Lookup caller, // provided by VM
            String invokedName,          // provided by VM
            MethodType invokedType,      // provided by VM
            MethodHandle descriptor,     // lambda descriptor
            MethodHandle impl)           // lambda body

The impl argument identifies the lambda method, either a desugared lambda body or the method named in a method reference.

A static (Integer::sum) or unbounded instance method (Integer::intValue) references are the 'simplest' or the most 'convenient', in the sense that they can be optimally handled by a 'fast-path' metafactory variant without the desugaring. This advantage is helpfully pointed out in TLE's "Metafactory variants":

By eliminating arguments where they are not needed, classfiles become smaller. And the fast path option lowers the bar for the VM to intrinsify the lambda conversion operation, enabling it to be treated as a "boxing" operation and faciliating unbox optimizations.

Naturally, an instance-capturing method reference (obj::myMethod) needs to provide the bounded instance as an argument to the method handle for invocation, which may mean the need of desugaring using 'bridge' methods.

Conclusion

I'm not exactly sure what is the lambda 'wrapper' you are hinting at, but even though the ultimate result of using your user-defined lambdas or method references are the same, the way that is reached seems to be quite different, and can be different in the future if that's not the case now. Hence, I suppose it's more likely than not that method references can be handled in a more optimal way by the metafactory.

🌐
Oracle
docs.oracle.com › javase › tutorial › java › javaOO › methodreferences.html
Method References (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
You use lambda expressions to create anonymous methods. Sometimes, however, 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.
🌐
Medium
medium.com › @Zimmendra › understanding-java-lambda-expressions-and-method-references-f59ce7f0c2b0
Understanding Java Lambda Expressions and Method References | by Heshanth Zimmendra | Medium
November 19, 2024 - Syntax: ClassName::methodName or instance::methodName · When the lambda expression just calls an existing method: If a lambda expression is simply calling an existing method, method references can be used as a more concise alternative.
🌐
TutorialsPoint
tutorialspoint.com › differences-between-lambda-expression-and-method-reference-in-java
Differences between Lambda Expression and Method Reference in Java?
Lambda expression is an anonymous method (method without a name) that has used to provide the inline implementation of a method defined by the functional interface while a method reference is similar to a lambda expression that refers a method without executing it.
Find elsewhere
🌐
Foojay
foojay.io › home › method reference vs lambda java challenge
Method Reference VS Lambda Java Challenge | foojay
August 23, 2021 - On the other hand, with method reference, the constructor will be invoked right away only where the method reference is assigned, not on the method invocation. ... With lambdas, every time the run method is invoked, the constructor will be invoked, ...
🌐
JetBrains
jetbrains.com › help › inspectopedia › Convert2MethodRef.html
Lambda can be replaced with method reference | Inspectopedia Documentation
2 weeks ago - While often it could be a matter of taste, method references are more clear and readable compared to lambdas.
🌐
Coderanch
coderanch.com › t › 704526 › java › Difference-Lambda-method-reference
Difference between Lambda and method reference? (Features new in Java 8 forum at Coderanch)
The method reference on the other hand is a closure - it captures the current value of System.out. If you would make the lambda / method reference serializable (by casting it to Consumer<Integer> & Serializable), the lambda could work while the method reference would cause serialization errors.
🌐
Medium
medium.com › codimis › what-is-method-reference-and-why-is-it-used-in-place-of-lambda-expressions-2a97fe01b07b
What is Method Reference and Why is It Used in Place of Lambda Expressions? | by Büşra Bozgöz | Codimis | Medium
March 22, 2024 - To briefly describe method references, we need to say that method references are a concise and more readable way of writing lambda expressions, but there are only particular use cases in which we can use them.
🌐
Kotlin Discussions
discuss.kotlinlang.org › support
Using lambda and method reference differ significantly in performance with Java 8 streams - Support - Kotlin Discussions
September 27, 2020 - I have found that when working with Java 8 streams, using lambda and method reference can differ significantly in performance. Here is the code to invert an array of 1 GB executed both sequentially and in parallel: inl…
🌐
Medium
medium.com › @edouard.kaiser › lambda-and-method-reference-133867e19c01
Lambda and method reference. Java 8 brought us the lambda… | by Edouard Kaiser | Medium
February 26, 2018 - This is an example for an anonymous ... point of view, what’s the difference? First, there is no way to reference, inside the expression, the lambda expression itself with this....
🌐
Baeldung
baeldung.com › home › java › core java › method references in java
Method References in Java | Baeldung
March 26, 2025 - As we’ve seen so far, method references are a great way to make our code and intentions very clear and readable. However, we can’t use them to replace all kinds of lambda expressions since they have some limitations.
🌐
DZone
dzone.com › coding › languages › java lambda: method reference
Java Lambda: Method Reference
October 11, 2018 - Thus, a lambda expression results in a form of anonymous class. Method reference is an important feature related to lambda expressions, which can let you reuse existing method definitions and pass them just like lambda expressions.
🌐
Kotlin Discussions
discuss.kotlinlang.org › language design
Method Reference vs Lambda - Language Design - Kotlin Discussions
February 28, 2021 - Recently I had a problem related to replacing lambda with method reference. Imagine that we have Button class which takes listener into constructor class Button( private val onClick: () -> Unit ) { fun performClick() = onClick() } Also we have ButtonClickListener class which represents button click logic class ButtonClickListener { fun onClick() { println("Button clicked") } } In ScreenView class we have lateinit property lateinit var listener:...
🌐
Dirask
dirask.com › posts › Java-8-difference-between-lambda-expression-and-method-reference-jMqXdj
Java 8 - difference between lambda expression and method reference
import java.io.*; import java.util.ArrayList; import java.util.List; public class Example { public static void main(String[] args) throws IOException { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); // Using lambda expression to print list items in lower case System.out.println("----- Lambda expression -----"); list.stream().map(x -> x.toLowerCase()) .forEach(x -> System.out.println(x)); // Using method reference to print list items in lower case System.out.println("----- Method reference -----"); list.stream().map(String::toLowerCase).sorted() .forEach(System.out::println); } }
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-method-references
Java Method References - GeeksforGeeks
Method references use the double colon (::) operator and are mainly used with functional interfaces. Introduced in Java 8 as an alternative to lambda expressions
Published   3 weeks ago
🌐
Dev.java
dev.java › learn › writing-lambda-expressions-as-method-references
Writing Lambda Expressions as Method References
October 26, 2021 - Defining your own classes, declaring member variables, methods, and constructors. ... How to model your immutable data with records to make your code simpler and more readable. ... Understanding numbers, characters and strings of characters. ... Leveraging inheritance in Java applications. ... Creating and using interfaces. ... Working with parameterized types. ... Using Lambda ...