Course topics

By WebNest Studio Engineering Team

Java - Core Tutorial

Method References

A method reference is shorthand notation for a lambda expression that does nothing but call an existing method. Instead of writing x -> ClassName.method(x), you can write ClassName::method, using the double-colon :: operator. Method references are purely syntactic sugar — they compile down to the same functional interface implementation a lambda would produce.

Why it matters

Method references are the shortest way to pass an existing method where a lambda is expected, and stream code is full of them: String::toUpperCase, System.out::println, ArrayList::new. You need to be able to read them at a glance and to know which of the four forms you are looking at.

The Four Kinds of Method References

Java recognizes four distinct forms, each matching a different lambda shape:

  • Static method reference — ClassName::staticMethod, equivalent to args -> ClassName.staticMethod(args). Example: Integer::parseInt.
  • Instance method reference on a particular object — instance::method, equivalent to args -> instance.method(args). Example: System.out::println.
  • Instance method reference on an arbitrary object of a type — ClassName::instanceMethod, equivalent to (obj, args) -> obj.instanceMethod(args), where the first lambda parameter becomes the object the method is called on. Example: String::toUpperCase.
  • Constructor reference — ClassName::new, equivalent to args -> new ClassName(args). Example: ArrayList::new.

Choosing Between a Lambda and a Method Reference

A method reference is preferred when the lambda body would do nothing except forward its arguments to an existing method, because it is shorter and more directly communicates intent. If any extra logic, transformation, or multiple statements are needed, a plain lambda is the better and often only option.

Example

All four kinds of method references in one program

Java
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

public class MethodReferenceDemo {
    public static void main(String[] args) {
        // 1. Static method reference
        Function<String, Integer> parse = Integer::parseInt;
        System.out.println(parse.apply("42"));

        // 2. Instance method reference on a particular object
        List<String> items = Arrays.asList("pen", "book");
        items.forEach(System.out::println);

        // 3. Instance method reference on an arbitrary object of a type
        Function<String, String> upper = String::toUpperCase;
        System.out.println(upper.apply("java"));

        // 4. Constructor reference
        Supplier<StringBuilder> builderFactory = StringBuilder::new;
        StringBuilder sb = builderFactory.get();
        sb.append("built via constructor reference");
        System.out.println(sb);
    }
}
Output
42
pen
book
JAVA
built via constructor reference

Common Mistakes

  • Confusing "ClassName::instanceMethod" (arbitrary object of a type) with "instance::method" (particular object) — the two look similar but the first argument role differs.
  • Trying to use a method reference when the lambda needs extra logic beyond a single direct call — a method reference cannot include additional statements.
  • Assuming a method reference is a different runtime mechanism from a lambda — it is purely a shorter syntax for the same functional interface implementation.

Exercise

Replace both lambdas with method references. The output must not change.

Expected output: ASHA then RAVI

Java · starter code
import java.util.List;

public class UseMethodReferences {
    public static void main(String[] args) {
        List<String> names = List.of("asha", "ravi");

        names.stream()
                .map(name -> name.toUpperCase())          // TODO: method reference
                .forEach(name -> System.out.println(name)); // TODO: method reference
    }
}
Show hints
  • A lambda that only calls a method on its parameter becomes ClassName::methodName.
  • A lambda that passes its parameter to a method of an existing object becomes object::methodName.
Show solution
Java · solution
import java.util.List;

public class UseMethodReferences {
    public static void main(String[] args) {
        List<String> names = List.of("asha", "ravi");

        names.stream()
                .map(String::toUpperCase)
                .forEach(System.out::println); // ASHA, RAVI
    }
}

Quick quiz

1. Which lambda is equivalent to Integer::parseInt?

  • A. s -> s.parseInt()
  • B. s -> new Integer(s)
  • C. () -> Integer.parseInt()
  • D. s -> Integer.parseInt(s)
Show answer

D. parseInt is a static method, so the argument of the lambda is passed to it.

2. What kind of method reference is ArrayList::new?

  • A. Constructor reference
  • B. Reference to a method of a particular object
  • C. Static method reference
  • D. It is not valid
Show answer

A. ClassName::new refers to a constructor, for example as a Supplier that creates a new list.

3. In String::length, on which object is length() called?

  • A. On the String class
  • B. On the first argument passed to the function
  • C. On an empty string
  • D. On the current object
Show answer

B. For an instance method referenced through its class, the first argument becomes the object the method is called on.

Interview questions

What are the four kinds of method reference?

Show answer

A static method, as in Integer::parseInt. An instance method of a particular object, as in System.out::println. An instance method of an arbitrary object of a given type, as in String::toUpperCase, where the first argument is the object the method is called on. And a constructor, as in ArrayList::new.

When should you use a lambda instead of a method reference?

Show answer

When the body does more than forward its arguments to one existing method, for example when it adds a calculation, passes extra arguments, or combines two calls. A method reference is only clearer when the lambda would be a single plain method call.

Key Points to Remember

  • Method references (::) are shorthand for lambdas that simply delegate to an existing method.
  • Four kinds exist: static, instance-of-particular-object, instance-of-arbitrary-object, and constructor references.
  • Use a method reference only when the lambda body would be nothing more than a single forwarding call.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering