In the lambda expression, the sBuilder
field is captured, but not evaluated. It will only be evaluated when the corresponding function interface method is invoked. At that point, the sBuilder
references the new instance created and assigned to the field with
sBuilder = new StringBuilder("2");
In the method reference, the sBuilder
field is evaluated immediately to produce a Consumer
instance. That value references the instance created in the static initializer
private static StringBuilder sBuilder = new StringBuilder("1");
and the Consumer
will operate on that one. You print the new one.
From the Java Language Specification, concerning the Run-Time Evaluation of Method References
The body of an invocation method depends on the form of the method
reference expression, as follows:
If the form is ExpressionName :: [TypeArguments] Identifier
or
Primary :: [TypeArguments] Identifier
, then the body of the
invocation method has the effect of a method invocation expression for
a compile-time declaration which is the compile-time declaration of
the method reference expression. Run-time evaluation of the method
invocation expression is as specified in §15.12.4.3, §15.12.4.4, and
§15.12.4.5, where:
The invocation mode is derived from the compile-time declaration as specified in §15.12.3.
The target reference is the value of ExpressionName
or Primary
, as determined when the method reference expression was
evaluated.
The arguments to the method invocation expression are the formal parameters of the invocation method.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…