typetools icon indicating copy to clipboard operation
typetools copied to clipboard

Possible more robust method reference resolution

Open jroper opened this issue 8 years ago • 1 comments

This isn't really an issue, but I just thought I'd let you know because in my project I was resolving method references from lambda instances and had copied some code from here to do it, but then I found out about a more robust way that uses 100% specced features, and so it will never break if the JDK version changes. The catch is, it only works if the SAM extends Serializable, so it's not useful as a general purpose solution for method reference resolution, however it may be worth doing as a more robust (and maybe more performant) solution before falling back to the current approach of attempting to read the constant pool.

The JDK spec requires that any lambda that implements a Serializable SAM must implement the writeReplace method, and this must return an instance of java.lang.invoke.SerializedLambda (See here and search for writeReplace to see the spec). SerializedLambda gives access to the method signature. So to use this you only have to reflectively invoke writeReplace if it exists, and check that the return type is SerializedLambda, the rest is public API. For my particular use case this works really well because I control the API that the lambdas are passed to that I want to resolve, so I can ensure that all the SAMs it accepts are Serializable.

jroper avatar May 06 '16 04:05 jroper

Thanks for the heads up @jroper. I was aware of the Serializable solution, but dismissed it early on since it obviously only works with Serializable lambdas. I think you're right though, it would be a nice, and possibly more reliable, adaptive solution for lambdas that do happen to be Serializable.

I'd be interested to learn how the performance of serializing a lambda to obtain type arguments compares to the constant pool approach. I'll probably look into this sometime when I get a chance...

jhalterman avatar May 06 '16 22:05 jhalterman