Master Java Method References and Optional: A Practical Guide
This article explains Java’s method reference syntax—including static, instance, and constructor references—demonstrates how to assign them to functional interfaces, explores the Optional class and its common methods, and shows how static factory methods like of replace constructors, all with clear code examples.
1. Concise Overview
Method references are expressed with the double colon :: and provide an alternative syntax for functional interfaces.
Static method reference: ClassName::staticMethod (e.g., Integer::parseInt)
Instance method reference: instance::method (e.g., str::substring)
Constructor reference: ClassName::new (e.g., User::new)
2. Method Reference Examples
public final class Integer {
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
}Assigning a method reference to a variable allows it to be used as a Function, demonstrating that method references are a form of functional interface, similar to lambda expressions.
public class User {
private String username;
private Integer age;
public User() {}
public User(String username, Integer age) {
this.username = username;
this.age = age;
}
@Override
public String toString() {
return "User{" + "username='" + username + '\'' + ", age=" + age + '}';
}
// Getter&Setter
}
public static void main(String[] args) {
// static function reference
Function<String, Integer> fun = Integer::parseInt;
Integer value = fun.apply("123");
System.out.println(value);
// instance function reference
String content = "Hello JDK8";
Function<Integer, String> func = content::substring;
String result = func.apply(1);
System.out.println(result);
// constructor reference
BiFunction<String, Integer, User> biFunction = User::new;
User user = biFunction.apply("mengday", 28);
System.out.println(user.toString());
// function reference as method argument
sayHello(String::toUpperCase, "hello");
}
private static void sayHello(Function<String, String> func, String parameter) {
String result = func.apply(parameter);
System.out.println(result);
}3. Optional Type
Java 8 includes the Optional class (originally from Guava) to avoid NullPointerException by explicitly handling possibly absent values.
package java.util;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() { this.value = null; }
public static <T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
private Optional(T value) { this.value = java.util.Objects.requireNonNull(value); }
public static <T> Optional<T> of(T value) { return new Optional<>(value); }
public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); }
public T get() {
if (value == null) { throw new java.util.NoSuchElementException("No value present"); }
return value;
}
public boolean isPresent() { return value != null; }
public void ifPresent(Consumer<? super T> consumer) {
if (value != null) consumer.accept(value);
}
public Optional<T> filter(Predicate<? super T> predicate) {
java.util.Objects.requireNonNull(predicate);
if (!isPresent()) return this;
return predicate.test(value) ? this : empty();
}
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
java.util.Objects.requireNonNull(mapper);
if (!isPresent()) return empty();
return Optional.ofNullable(mapper.apply(value));
}
public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
java.util.Objects.requireNonNull(mapper);
if (!isPresent()) return empty();
return java.util.Objects.requireNonNull(mapper.apply(value));
}
public T orElse(T other) { return value != null ? value : other; }
public T orElseGet(Supplier<? extends T> other) { return value != null ? value : other.get(); }
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) return value;
else throw exceptionSupplier.get();
}
}The static of factory method is now a common pattern that replaces public constructors, providing a clearer way to create instances.
public class User {
private String username;
private Integer age;
private User() {}
private User(String username, Integer age) {
this.username = username;
this.age = age;
}
public static User of() { return new User(); }
public static User of(String username, Integer age) { return new User(username, age); }
}Example usage of Optional in a main method demonstrates checking presence, retrieving values, providing defaults, and executing actions when a value exists.
public static void main(String[] args) {
// Optional is part of Java 8, originally from Guava
// It helps avoid NullPointerException
String msg = "hello";
Optional<String> optional = Optional.of(msg);
boolean present = optional.isPresent();
String value = optional.get();
String hi = optional.orElse("hi");
optional.ifPresent(opt -> System.out.println(opt));
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
