В первом методе System.out
вычисляется немедленно в операторе возврата.
Эквивалентная лямбда будет выглядеть так, как если бы вы вывели System.out
в переменную, которая затем фактически становится окончательным закрытием:
Runnable createLambdaWithCapture() {
PrintWriter foo = System.out;
return () -> foo.println(); // foo is captured and effectively final
}
Во втором методе System.out (который является статическим полем) не является окончательным и может быть изменен позднее во время выполнения.Он не вызывается до Runnable::run
.
System.out = aPrintStream;
Runnable runnable1 = createLambdaWithCapture();
Runnable runnable2 = createLambdaWithApparentCapture();
System.out = anotherPrintStream;
runnable1.run(); // prints to aPrintStream
runnable2.run(); // prints to anotherPrintStream