Master Java 8 Method References and Optional: A Practical Guide
This article explains Java 8's method reference syntax—including static, instance, and constructor references—shows how to assign them to functional interfaces, introduces the Optional class for null‑safe programming, and demonstrates the static‑factory‑method (of) pattern with clear code examples.
Method References
Java 8 introduced method references as a concise alternative to lambda expressions. There are three kinds of method references:
Static method reference: Class::staticMethod (e.g., Integer::parseInt)
Instance method reference: instance::method (e.g., str::substring)
Constructor reference: Class::new (e.g., User::new)
public final class Integer {
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s, 10);
}
}Method references can be assigned to functional interfaces. For example, Function<String,Integer> fun = Integer::parseInt; assigns the static method reference to a Function that converts a String to an Integer. Instance and constructor references work similarly.
public static void main(String[] args) {
// static method reference
Function<String, Integer> fun = Integer::parseInt;
Integer value = fun.apply("123");
System.out.println(value);
// instance method 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);
// method reference as a parameter
sayHello(String::toUpperCase, "hello");
}
private static void sayHello(Function<String, String> func, String parameter) {
String result = func.apply(parameter);
System.out.println(result);
}Optional – A Null‑Safe Wrapper
Java 8 added java.util.Optional to help avoid NullPointerException. It provides a rich API for checking presence, retrieving values, and transforming them.
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() { this.value = null; }
private Optional(T value) { this.value = Objects.requireNonNull(value); }
public static <T> Optional<T> empty() { return (Optional<T>) EMPTY; }
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 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) { Objects.requireNonNull(predicate); return !isPresent() ? this : predicate.test(value) ? this : empty(); }
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper); return !isPresent() ? empty() : Optional.ofNullable(mapper.apply(value)); }
public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { Objects.requireNonNull(mapper); return !isPresent() ? empty() : 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(); }
}Typical usage in main:
String msg = "hello";
Optional<String> optional = Optional.of(msg);
boolean present = optional.isPresent();
String value = optional.get();
String hi = optional.orElse("hi");
optional.ifPresent(System.out::println);Static‑Factory‑Method (of) Pattern
Many classes replace public constructors with a private constructor and a public static of method that returns a new instance, improving readability and encapsulation.
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); }
}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.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
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.
