There are four: static (Integer::parseInt), bound to a specific instance (System.out::println, captures that object), unbound on an arbitrary instance of a type (String::toLowerCase, where the first lambda parameter becomes the receiver), and constructor (ArrayList::new).
The subtle one is unbound versus bound: String::length applies length() to whichever String is passed in, whereas someList::add always targets that one list. Method references are just sugar for lambdas, so use them when they read more clearly and fall back to a lambda when arguments need reordering or extra logic.
- Confusing a static method reference with an unbound instance method reference.
- Using a lambda where a method reference is clearer, or the reverse.