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 toargs -> ClassName.staticMethod(args). Example:Integer::parseInt. - Instance method reference on a particular object —
instance::method, equivalent toargs -> 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 toargs -> 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
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);
}
}
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
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
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.
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