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. Answer from CrouchonaHammock on reddit.com
🌐
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 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.

🌐
Reddit
reddit.com › r/java › lambda x method reference taste
r/java on Reddit: lambda x method reference taste
January 21, 2022 -

Hello guys, I'm jr web back-end and during my "trainee introduction" one of my seniors and my job's SonarQube forced me to switch lambda expressions for method reference. I've searched a bit about this change wondering if all of this is about performance, or patterns or code reduction but I didn't find something solid, I know it's probably has been discussed here, but I want more opinions about. For me, lambda expression is way better to read and code, please don't judge me :D

🌐
Reddit
reddit.com › r/javahelp › passing lambda vs passing method reference to calling lambda
r/javahelp on Reddit: Passing lambda vs passing method reference to calling lambda
July 17, 2022 -

In the java function package, there are many functional interfaces to represent common lambdas. I have a method which takes one of theswe as a parameter, and passes it into another method which takes the same kind of lambda, like so:

... forEach(Consumer<T> operation) {
    toStream()
        .forEach(
            //operation || operation::apply
        );
}

There would be two ways to pass in the operation. Either I could just pass it in, or I could pass it using the method reference of calling the lambda. My question is: is there any actual difference between these? Does passing it only call it once, whereas using the method reference calls it twice? Which one is more efficient, or are they the same?

Top answer
1 of 5
1
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://imgur.com/a/fgoFFis ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
2 of 5
1
Functionally they are the same, but passing the consumer directly is more performant
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.

🌐
TutorialsPoint
tutorialspoint.com › differences-between-lambda-expression-and-method-reference-in-java
Differences between Lambda Expression and Method Reference in Java?
The arrow (->) operator can be used to connect the argument and functionality in a lambda expression while the (::) operator separates the method name from the name of an object or class in a method reference. ... import java.util.*; public class LambdaMethodReferenceTest { public static void ...
🌐
Coderanch
coderanch.com › t › 704526 › java › Difference-Lambda-method-reference
Difference between Lambda and method reference? (Features new in Java 8 forum at Coderanch)
Note that a method reference is only a closure if it's a method reference called on an instance. If the part before the :: is a class name then there would be no difference. For instance, the following pairs are more or less identical (nothing is captured): SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD ...
Find elsewhere
🌐
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 - We can see examples of four cases, and in the above image, each example is numbered in order. To easily understand the use of the method reference, we used a class that has no dependencies on other classes. In each example, the version that can be written using the Lambda expression is given in the comment line.
🌐
Baeldung
baeldung.com › home › java › core java › method references in java
Method References in Java | Baeldung
March 26, 2025 - As it is a varargs method, it will work in any lambda expression, no matter the referenced object or number of parameters inferred. ... In this quick tutorial, we learned what method references are in Java and how to use them to replace lambda expressions, thereby improving readability and clarifying the programmer’s intent.
🌐
Reddit
reddit.com › r/java › the elusive and beautiful java method reference
r/java on Reddit: The elusive and beautiful Java Method Reference
February 20, 2022 - News, Technical discussions, research papers and assorted things of interest related to the Java programming language NO programming help, NO learning Java related questions, NO installing or downloading Java questions, NO JVM languages - Exclusively Java ... Archived post. New comments cannot be posted and votes cannot be cast. Share ... IMHO this was titled pretty poorly. It's really about the Eclipse Collections library and how you can use some of its parts to pass arguments to method references. ... Yeah, from the title I was expecting an article full of “don’t use lambdas, use method references”, but once I saw Predicate2 , i caught on to stuff.
🌐
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 - The most important thing they don’t say is that, if the referenced method is the instance method of an arbitrary object of a particular type, the object (the receiver of the method) is considered to be the first argument in the functional interface used. ... The java.util.function.Function<String,String> means the lambda expression has to respect the signature:
🌐
Foojay
foojay.io › home › method reference vs lambda java challenge
Method Reference VS Lambda Java Challenge | foojay
August 23, 2021 - In this Java Challenge, we will explore how lambdas and method references behave so that you can really understand how they work!
🌐
Dirask
dirask.com › posts › Java-8-difference-between-lambda-expression-and-method-reference-jMqXdj
Java 8 - difference between lambda expression and method reference
extracting many statements from lambda expression in a method and referencing it may improve the readability of the code,
🌐
DZone
dzone.com › coding › java › java lambda expressions vs method references
Java Lambda Expressions vs Method References
April 9, 2013 - Now we can use lambda expressions to implement functional interfaces as we have seen in previous posts, but the lambda expressions are not the only mechanism we can use for this purpose. Particularly where there are preexisting code that we would like to reuse we can simplify the implementation of the functional interface by using method references.
🌐
Blogger
javarevisited.blogspot.com › 2017 › 08 › how-to-convert-lambda-expression-to-method-reference-in-java8-example.html
How to Convert a Lambda Expression to Method Reference in Java 8?
If you already have that code in form of a method then instead of passing the new code as lambda you can pass the name of the method and that's known as method reference. That's it, but I know, it's easier said than done, hence I have provided ...
🌐
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.
🌐
Medium
medium.com › @damian.kolasa › performance-implications-of-lambdas-and-method-references-when-mapping-a-stream-in-java-79f6e2da6806
Performance implications of lambdas and method references when mapping a stream in Java | by Damian Kolasa | Medium
June 13, 2018 - Because Method References don’t allow for partial application they are not included in this part of the test (would you like to see them added to Java?). ... To minimize cleverness of Just In Time compiler bias is a method argument. Locally referencing coarse grained lambda expression