1

From java.lang.invoke.LambdaMetafactory:

The recommended mechanism for evaluating lambda expressions is to desugar the lambda body to a method, invoke an invokedynamic call site whose static argument list describes the sole method of the functional interface and the desugared implementation method, and returns an object (the lambda object) that implements the target type.

And from inspection this is at least what Oracle JDK does.

My question: given a lambda object is there a way to find the name (or a handle to) the implementation method? Alternately, given a list of implementation methods, is there a way to tell which one corresponds to a given lambda object?

OrangeDog
  • 36,653
  • 12
  • 122
  • 207
  • 1
    If you’re asking for a general (portable) way that will still work tomorrow, I’m afraid [this is the answer](https://stackoverflow.com/a/19845393/2711488). All existing solutions are either, highly implementation specific or limited to only a few cases, or both. But maybe, there is a solution for your specific use case… – Holger May 19 '17 at 17:24
  • Well clearly, as the specification doesn't even require any sort of method handle to be involved. – OrangeDog May 22 '17 at 09:35
  • 1
    I didn’t intent to go *that* formal. Considering the documented collaboration between compiled code and the `LambdaMetaFactory` (if we decide to compile Java source code to bytecode using it), which is today’s practice, we still have to face the fact, that the particular JRE’s `LambdaMetaFactory` implementation has a lot of freedom. Most notably, there is no requirement for the returned class, to contain a reference to the target method at all. It could be a proxy, only implementing the functional interface, delegating to another mechanism for invoking the target method. – Holger May 22 '17 at 09:45
  • 1
    Another practical example is that I remember discussions about exempting such generated classes from Instrumentation, which is a reason for me, not to recommend a solution capturing and analyzing these classes via Instrumentation, when I already know that it might stop working in one of the next versions… – Holger May 22 '17 at 09:47

1 Answers1

2

You could access the ConstantPool of the lambda class (i.e. by using sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(class)) and then search for the method reference. You have to ignore the object constructor as well as autoboxing/unboxing method references, the remaining method reference is the implementing method.

Nevay
  • 784
  • 5
  • 9
  • 2
    Aha, the secret sun packages – OrangeDog May 19 '17 at 17:52
  • 1
    Of course, the lambda object could be exactly a method reference to the `Object()` constructor or one of the boxing/unboxing methods. Needless to say, how many implementation details are assumed when using the method… – Holger May 19 '17 at 18:07