Consider following class:
class Foo<T> {
void handle(T t) {
System.out.println("handling " + t);
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
Foo<Integer> f = new Foo<>();
list.forEach(f::handle); // compiles fine
//list.forEach(obj -> f.handle(obj));// compilation error
f = new Foo<>(); // reassign f
}
}
Why do I get compilation error for obj -> f.handle(obj), but not for f::handle?
Those are two different constructs that are doing two different things. In the first case, you are getting the method reference of a specific object: this needs to be done only once, after which the JVM has its own reference (so effectively final) to the object
fand can call thehandlemethod. In the second case, at each call the JVM has to resolve thefreference and it thus complains thatfmust befinal. You could easily write code that setsftonullwhile theforEachis running and thus cause a NPE.