Search code examples
javafunctionserializationlambdacapture

How to get lambda (Function instance) captured value in runtime?


Imagine we have some third party class that we can't change.
That class has a java.lang.Function field, setter and getter.
Setter accepts not a Function, but only a one function argument, and initializes function field via lambda.

    private class ThirdPartyClass {
        private Function<Integer, Integer> func;

        public void setFunc(Integer i2) {
            this.func = i1 -> i1 + i2;
        }

        public Function<Integer, Integer> getFunc() {
            return func;
        }
    }

In my code, I am using setter first and then getter to obtain a Function.

        //on application startup
        thirdPartyClass.setFunc(100);
        
        // after a while in the other module
        Function<Integer, Integer> func = thirdPartyClass.getFunc();
    

This is a very simplified example. Actual third party code is spring state machine library, particularly this method in the role of a setter, and this getter.

How can I get function parameter that was passed to setter having only the Function object itself ?
Is it even possible ?

I found some Function lambdas serialization tricks (via types intersection feature), that allows to obtain java.lang.invoke.SerializedLambda instance, which has captured value in it, process is described in that question:
How to make function Serializable in generic way

But seems it is not working in my case, because it works only if intersection is applied on lambda creation. Process is described in that one
Serialization of a lambda after its creation


Solution

  • You can't. The returned function is acting as a closure. In effect, the passed argument(s) that are "embedded" in the returned function are out scope and as such they are not accessible.