← Back to Advanced Java Course | Chapter 3: Functional Programming | Lesson 5 of 6

Java Method References

Introduction to Method References

Method references are a shorthand syntax for writing simple lambda expressions that do nothing but call an existing method. They use the double colon (::) operator to refer to that method by name without actually invoking it right away.

Example: Introduction to Method References

java
import java.util.function.Consumer;
public class Main {
	public static void main(String[] args) {
		Consumer<String> printer = System.out::println; // shorthand for s -> System.out.println(s)
		printer.accept("Using ::");
	}
}

Reference to an Instance Method of a Particular Object

You can reference an instance method belonging to one specific, already-existing object using the format 'instance::instanceMethod'. This binds the call directly to that particular object, so every invocation of the reference operates on the same instance.

Example: Reference to an Instance Method of a Particular Object

java
import java.util.function.Supplier;
public class Main {
	public static void main(String[] args) {
		String greeting = "Hello";
		Supplier<Integer> lengthGetter = greeting::length; // bound to this specific instance
		System.out.println(lengthGetter.get());
	}
}

Reference to an Instance Method of an Arbitrary Object

You can also reference an instance method of an arbitrary object of a given type using the format 'Type::instanceMethod'. In this style, the first argument supplied to the functional interface becomes the object the method is actually called on, rather than a fixed instance you named up front.

Example: Reference to an Instance Method of an Arbitrary Object

java
import java.util.function.Function;
public class Main {
	public static void main(String[] args) {
		Function<String, Integer> toLength = String::length; // first argument becomes the receiver
		System.out.println(toLength.apply("arbitrary"));
	}
}

Constructor References

You can write references to constructors using the format 'Class::new', which gives you a clean, reusable way to instantiate objects dynamically, for example as a Supplier passed into a stream's collect() or map() call.

Example: Constructor References

java
import java.util.function.Supplier;
import java.util.ArrayList;
public class Main {
	public static void main(String[] args) {
		Supplier<ArrayList<String>> listMaker = ArrayList::new;
		ArrayList<String> list = listMaker.get();
		list.add("created via constructor reference");
		System.out.println(list);
	}
}

Method References vs Lambdas

Method references read more concisely than lambdas whenever you're simply forwarding to an existing method unchanged. But if you need to transform arguments, add extra logic, or combine several steps together, a standard lambda expression is the better, more flexible choice.

Example: Method References vs Lambdas

java
import java.util.function.Function;
public class Main {
	public static void main(String[] args) {
		Function<String, Integer> ref = String::length; // simple forward, reads cleanly
		Function<String, Integer> lambda = s -> s.length() + 1; // extra logic needs a lambda
		System.out.println(ref.apply("abc") + " " + lambda.apply("abc"));
	}
}
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.