Lambda expressions are compiled into synthetic methods with an unspecified name. There can be other unspecified subtleties, like the method’s argument order for captured variables. Further, when the lambda expression accesses the this
instance, there are two options, compile it to an instance method or compile it to a static
method receiving the instance like an ordinary parameter.
For the resulting behavior of the lambda expression, this makes no difference. But the serialized form depends on these details and hence, is very fragile. You don’t even need to change the class, recompiling it with a different compiler could change these details. In fact, even recompiling with the same compiler could change the outcome, e.g. when the compiler’s behavior depends on some hash map with iteration order randomization.
In practice, compiler vendors try to reduce such effects and produce stable results, even when not being mandated by the specification. But when you change the class, all bets are off. One aspect you can easily see in the compiled class file is that compilers add a number to the method name, depending on the order of occurrence in the source file. Inserting another lambda expression or removing one can change the numbers of all subsequent lambda expressions.
So, a changed A
class can be incompatible to your serialized lambda expression, and the best thing that can happen, is an exception during deserialization due to a mismatch. Worse than that, it could select the wrong lambda expression, because it happened to have a compatible combination of name and signature.
A safer construct is method references, as they refer to the actual target method, which is not affected by other lambda expressions or method references within the same class. However, not every method reference is compiled as a direct reference on the byte code level. In certain cases, like when referring to a varargs method or calling a super
method or a method on an intersection type whose declaring class does not match the erased type, the compiler may generate a stub method for the invocation, similar to a lambda expression. So you still have to be careful.